读取单列 CSV 文件的更快方法

Posted

技术标签:

【中文标题】读取单列 CSV 文件的更快方法【英文标题】:Quicker way to read single column of CSV file 【发布时间】:2013-11-13 15:04:50 【问题描述】:

我正在尝试尽快将CSV 文件的单个列读取到R。我希望将标准方法减少 10 倍的将列放入 RAM 所需的时间。

我的动机是什么?我有两个文件;一个叫Main.csv,它是300000行500列,一个叫Second.csv,它是300000行5列。如果我system.time() 命令read.csv("Second.csv"),则需要2.2 秒。现在,如果我使用以下两种方法中的任何一种来读取Main.csv 的第一列(这是Second.csv 的20%,因为它是1 列而不是5 列),它将花费40 多秒。 这与读取整个 600 MB 文件所需的时间相同——显然是不可接受的。

方法一

colClasses <- rep('NULL',500)

colClasses[1] <- NA
system.time(
read.csv("Main.csv",colClasses=colClasses)
) # 40+ seconds, unacceptable

方法二

 read.table(pipe("cut -f1 Main.csv")) #40+ seconds, unacceptable

如何减少这个时间?我希望有一个R 解决方案。

【问题讨论】:

您可以将数据加载到数据库中并仅选择所需的列或使用 HDF5 文件而不是 csv。 @zero323 我需要一些可以是io 的东西:PythonJavaR require(data.table); fread( "path/to/file/Main.csv" ) 将立即提高您的速度。 我的old POC package 在这里可能会很有趣,它提供了一种以特殊二进制格式编写data.frame 的方法,以后可以用于一次仅读取几个变量。基本上它是save/readRDS 的包装器,并将列写入单独的文件等。更多详细信息:***.com/questions/4756989/… 你的 csv 文件真的是逗号分隔的吗?我认为scan(pipe("cut -f1 -d, Main.csv")) 可能值得一试。 【参考方案1】:

我建议

scan(pipe("cut -f1 -d, Main.csv"))

这与最初的提案 (read.table(pipe("cut -f1 Main.csv"))) 在几个不同的方面有所不同:

由于文件是逗号分隔且cut默认采用制表符分隔,所以需要指定d,来指定逗号分隔 对于简单/非结构化数据读取,scan()read.table 快得多。

根据 OP 的 cmets,这大约需要 4 秒而不是 40 多秒。

【讨论】:

看到你可以在读取文件之前用 Linux 命令行嵌套真是太神奇了。我什至可以在读取原始文件之前将我的 Python 清理程序放在管道命令中清理数据!我想知道是否可以有效地使用扫描从标准输入逐行读取表(每行是一行)? 绝对精彩。 @B.Mr.W.:恐怕你不会做得更好(我在其他地方看到了你的问题,但你的限制非常强:很难想象一种在 R 中逐行读取而无需大量开销的方法。)我认为scan 不会比readLines 快,但你为什么不试试看它是怎么回事? @BenBolker 实际上您可以将fread 直接与系统命令一起使用,所以这...fread( "cut -f1 -d, Main.csv" ) 可以更快吗? 也许吧,但scan() 确实没有太多开销(与read.table() 相比)【参考方案2】:

在blog 中有读取大型 CSV 文件的方法的速度比较。 fread 是最快的一个数量级。

如上面cmets中提到的,可以使用select参数来选择读取哪些列——所以:

fread("main.csv",sep = ",", select = c("f1") ) 

会起作用

【讨论】:

你能选择读入哪些行吗?即,按列的条件选择行? fread 等效于 SELECT col_1, col_2 FROM file WHERE col_3 &gt; 30

以上是关于读取单列 CSV 文件的更快方法的主要内容,如果未能解决你的问题,请参考以下文章

计算两个 csv 文件之间差异的更快方法

在 C++ 中通过 csv 文件的更快方法

HSQL CSV 文本表正在读取多行的单列

读取pandas修改单列数据类型

读取固定宽度文件的更快方法

python csv读取方法及常用的csv读取代码