AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / coding / 问题 / 77771626
Accepted
Dan
Dan
Asked: 2024-01-07 09:39:33 +0800 CST2024-01-07 09:39:33 +0800 CST 2024-01-07 09:39:33 +0800 CST

将 CSV 文件缓慢解析为向量图

  • 772

我正在尝试读取 CSV 文件并将其解析为向量图。因此,映射的键是 CSV 中的列名称,映射的值是包含 CSV 中的值列的向量。

我使用内置函数clojure.data.csv来读取文件,尽管 CSV 文件(在此处找到)只有 32 MB,但我的代码运行速度确实相当慢。

(require '[clojure.data.csv :as csv]
         '[clojure.java.io :as io])

(defn csv->df [file-path]
  (with-open [reader (io/reader file-path)]
    (let [in-file (csv/read-csv reader)
          names (first in-file)
          data (rest in-file)]
      (zipmap (map keyword names) (apply mapv vector data)))))

(csv->df "data/flights.csv")

我怀疑我正在做一些与惰性序列相关的愚蠢的事情,因为作为 Clojure 新手,我仍然在掌握它们,但我无法确定问题的根本原因。

是否可以重组此功能,使其运行速度不至于缓慢?

csv
  • 2 2 个回答
  • 70 Views

2 个回答

  • Voted
  1. Best Answer
    amalloy
    2024-01-07T13:08:24+08:002024-01-07T13:08:24+08:00

    您不会从懒惰中受益,因为转置矩阵(这就是apply map vector正在做的事情)不能偷懒。但你并没有做任何特别错误的事情。read-csv在我的机器上进行的测试中,调用该文件并迭代结果所需的时间是 9 秒。你的函数大约需要两倍的时间。因此,您的处理速度并不快,但如果您以某种方式设法在零时间内完成所有后处理,那么您所希望的最好结果是整个过程加速 50%。

    我认为如果您使用 clojure.data.csv,这些成本是不可避免的。将内容打包到整洁的 Clojure 数据结构中非常方便,但它并不是免费的。我尝试使用 FastCSV 进行比较:读取并丢弃整个文件的速度大约快 20 倍,并且从文件生成向量=向量的速度也同样快。转置仍然很慢,但整个过程只需 5 秒,而不是您的函数的 17 秒。这是我写的:不灵活且笨重,但它产生相同的结果并且足够简单。如果性能确实很重要,您可以融合转置步骤,从不构建行向量,而是为每列维护一个单独的向量,并为遇到的每一行更新每个向量。

    (defmacro row-fn [[arg] & body]
      (let [x (gensym 'arg)]
        `(reify java.util.function.Consumer
           (accept [this ~x]
             (let [~(with-meta arg {:tag `CsvRow}) ~x]
               ~@body)))))
    
    (defn fastcsv->df [file-path]
      (let [headers (promise)
            csv (-> (CsvReader/builder)
                    (.build (io/reader file-path))
                    (.spliterator))
            rows (atom (transient []))]
        (.tryAdvance csv (row-fn [row]
                           (deliver headers (map keyword (.getFields row)))))
        (.forEachRemaining csv (row-fn [row]
                                 (swap! rows conj! (.getFields row))))
        (zipmap @headers (apply map vector (persistent! @rows)))))
    
    • 4
  2. Harold
    2024-01-08T00:45:54+08:002024-01-08T00:45:54+08:00

    这就是TMD的目的。

    user> (require '[tech.v3.dataset :as ds])
    nil
    user> (time (def ds (ds/->dataset "https://vincentarelbundock.github.io/Rdatasets/csv/nycflights13/flights.csv")))
    "Elapsed time: 2477.121908 msecs"
    #'user/ds
    

    这在 2.5 秒内构建了数据集,其中从互联网下载数据集大约需要 1 秒。

    而且,如您所愿,TMD 数据集在逻辑上是列名称到列数据的映射:

    user> (get ds "year")
    #tech.v3.dataset.column<int16>[336776]
    year
    [2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013...]
    

    而且,作为奖励(如您所见),数据是有类型的 - 年份列是 336776 个原始 Java 16 位int。这将占用更少的内存。

    • 3

相关问题

  • 将 CSV 读入 Spark DataFrame 的两种方法有何不同?

  • 无法使用环境库运行 Julia 脚本

  • awk csv引用字段需要大写每个单词

  • 如何使用 terraform csvdecode 读取双引号字符串值?

  • BAT 文件 - 根据文件内容重命名多个 .csv 文件

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    Vue 3:创建时出错“预期标识符但发现‘导入’”[重复]

    • 1 个回答
  • Marko Smith

    为什么这个简单而小的 Java 代码在所有 Graal JVM 上的运行速度都快 30 倍,但在任何 Oracle JVM 上却不行?

    • 1 个回答
  • Marko Smith

    具有指定基础类型但没有枚举器的“枚举类”的用途是什么?

    • 1 个回答
  • Marko Smith

    如何修复未手动导入的模块的 MODULE_NOT_FOUND 错误?

    • 6 个回答
  • Marko Smith

    `(表达式,左值) = 右值` 在 C 或 C++ 中是有效的赋值吗?为什么有些编译器会接受/拒绝它?

    • 3 个回答
  • Marko Smith

    何时应使用 std::inplace_vector 而不是 std::vector?

    • 3 个回答
  • Marko Smith

    在 C++ 中,一个不执行任何操作的空程序需要 204KB 的堆,但在 C 中则不需要

    • 1 个回答
  • Marko Smith

    PowerBI 目前与 BigQuery 不兼容:Simba 驱动程序与 Windows 更新有关

    • 2 个回答
  • Marko Smith

    AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String”

    • 1 个回答
  • Marko Smith

    我正在尝试仅使用海龟随机和数学模块来制作吃豆人游戏

    • 1 个回答
  • Martin Hope
    Aleksandr Dubinsky 为什么 InetAddress 上的 switch 模式匹配会失败,并出现“未涵盖所有可能的输入值”? 2024-12-23 06:56:21 +0800 CST
  • Martin Hope
    Phillip Borge 为什么这个简单而小的 Java 代码在所有 Graal JVM 上的运行速度都快 30 倍,但在任何 Oracle JVM 上却不行? 2024-12-12 20:46:46 +0800 CST
  • Martin Hope
    Oodini 具有指定基础类型但没有枚举器的“枚举类”的用途是什么? 2024-12-12 06:27:11 +0800 CST
  • Martin Hope
    sleeptightAnsiC `(表达式,左值) = 右值` 在 C 或 C++ 中是有效的赋值吗?为什么有些编译器会接受/拒绝它? 2024-11-09 07:18:53 +0800 CST
  • Martin Hope
    The Mad Gamer 何时应使用 std::inplace_vector 而不是 std::vector? 2024-10-29 23:01:00 +0800 CST
  • Martin Hope
    Chad Feller 在 5.2 版中,bash 条件语句中的 [[ .. ]] 中的分号现在是可选的吗? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench 为什么双破折号 (--) 会导致此 MariaDB 子句评估为 true? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng 为什么 `dict(id=1, **{'id': 2})` 有时会引发 `KeyError: 'id'` 而不是 TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String” 2024-03-20 03:12:31 +0800 CST
  • Martin Hope
    MarkB 为什么 GCC 生成有条件执行 SIMD 实现的代码? 2024-02-17 06:17:14 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve