Vroom/fread 不会读取 LARGE .csv 文件 - 无法对其进行内存映射
Posted
技术标签:
【中文标题】Vroom/fread 不会读取 LARGE .csv 文件 - 无法对其进行内存映射【英文标题】:Vroom/fread won't read LARGE .csv file - cannot memory map it 【发布时间】:2021-08-05 09:19:10 【问题描述】:我有一个重 112GB 的 .csv
文件,但 vroom
和 data.table::fread
都不会打开它。即使我要求读取 10 行或几列,它也会抱怨映射错误:无法分配内存。
df<-data.table::fread("FINAL_data_Bus.csv", select = c(1:2),nrows=10)
System errno 22 unmapping file: Invalid argument
Error in data.table::fread("FINAL_data_Bus.csv", select = c(1:2), nrows = 10) :
Opened 112.3GB (120565605488 bytes) file ok but could not memory map it. This is a 64bit process. There is probably not enough contiguous virtual memory available.
另一方面,read.csv
会愉快地阅读这十行。
为什么 vroom
或 fread
不使用通常的 altrep 读取它,即使是 10 行?
【问题讨论】:
假设你在工作目录中,试试这个代码fread(cmd="head -n 10 FINAL_data_Bus.csv", select=1:2)
。
行得通,谢谢。这会告诉我什么?
它显示前 10 行(包括包含列名的行)。您需要读取所有数据吗?您可以尝试分块读取它,同时仅过滤您工作所需的列和行。请注意,CL split
命令对于拆分非常方便。您的数据集的列数和行数是多少?如果您不知道,请尝试以下操作:ncol(fread(cmd="head -n 10 FINAL_data_Bus.csv"))
和 system("wc -l FINAL_data_Bus.csv", TRUE)
。
@B.ChristianKamgang - 这些 cmets 将很有用地成为答案,因为问题经常出现,并且您的方法提供了检查方法和分块指导。我的想法和要求。
@B.ChristianKamgang 所以我们必须先拆分大的 csv 文件并使用某种循环读取所有块?如果是这样,来自github.com/BurntSushi/xsv 的xsv
比CL split
做得更好,因为它在每个块中保留了标题。但是,我仍在寻找一种无需先拆分即可读取大型 gzip 压缩 csv 文件的方法。
【参考方案1】:
data.table
包的主要创建者https://github.com/Rdatatable/data.table/issues/3526 讨论了这件事。请参阅 Matt Dowle 本人在https://github.com/Rdatatable/data.table/issues/3526#issuecomment-488364641 的评论。据我了解,问题的要点是,要从带有fread
的巨大 csv 文件中读取 10 行,整个文件都需要进行内存映射。所以fread
不能单独使用,以防你的csv文件对你的机器来说太大了。如果我错了,请纠正我。
另外,我无法将vroom
用于处理超过 RAM 的 csv 文件。任何指向此目的的指针将不胜感激。
对我来说,查看一个巨大的(gzip 压缩的)csv 文件最方便的方法是使用来自https://bioinf.shenwei.me/csvtk/ 的小型命令行工具csvtk
例如,检查尺寸
csvtk dim BigFile.csv.gz
然后,检查前 100 行的 head
csvtk head -n100 BigFile.csv.gz
通过
更好地了解上述情况csvtk head -n100 BigFile.csv.gz | csvtk pretty | less -SN
这里我使用了less
命令,在https://github.com/bmatzelle/gow“Windows 上的 Gnu”中可用
请注意——很多人建议使用命令
wc -l BigFile.csv
检查没有。 lines
来自一个大的 csv 文件。在大多数情况下,它将等于否。的rows
。但如果大 csv 文件包含换行符在单元格内,使用电子表格术语,上述命令将不会显示否。的rows
。在这种情况下,没有。 lines
的编号与编号不同。的rows
。因此建议使用csvtk dim
或csvtk nrow
。其他 csv 命令行工具,如 xsv
、miller
也将显示正确的结果。
另一个警告 - 短命令 fread(cmd="head -n 10 BigFile.csv")
不建议预览前几行,以防某些列在 0301、0542 等数据中包含重要的前导零,因为没有列规范,fread
会将它们解释为整数,并且不会显示此类列的前导零。例如,在我必须分析的某些数据库中,特定列中的第一个数字零表示它是Revenue Receipt
。所以最好使用像csvtk
、miller
、xsv
和less -SN
这样的命令行工具来预览一个大的 csv 文件,该文件“按原样”显示文件,没有任何潜在的错误解释。
PS1:即使是 MS Excel 和 LibreOffice Calc 等电子表格,默认情况下也会在 csv 文件中丢失前导零。 LibreOffice Calc 实际上在预览窗口中显示前导零,但在加载文件时会丢失它们!我还没有找到默认情况下不会丢失 csv 文件中前导零的电子表格。
PS2:我已经在https://***.com/a/68693819/8079808发布了我查询超大 csv 文件的方法
编辑:
VROOM 在处理大文件时确实有困难,因为它需要将索引以及从文件中读取的任何数据存储在内存中。见开发帖https://github.com/r-lib/vroom/issues/203
【讨论】:
以上是关于Vroom/fread 不会读取 LARGE .csv 文件 - 无法对其进行内存映射的主要内容,如果未能解决你的问题,请参考以下文章
c_cpp Factorial_of_Large_Number
Bitbucket git clone BUG: remote-curl.c:1342: The entire rpc->buf should be large than LARGE_PACKE
Python int too large to convert to C long