将非常大的 CSV 数据集加载到 Python 和 R 中,Pandas 陷入困境
Posted
技术标签:
【中文标题】将非常大的 CSV 数据集加载到 Python 和 R 中,Pandas 陷入困境【英文标题】:Loading very large CSV dataset into Python and R, Pandas struggles 【发布时间】:2018-04-13 00:50:43 【问题描述】:我正在将一个巨大的 csv (18GB) 加载到内存中,并注意到 R 和 Python 之间存在很大差异。这是在 AWS ec2 r4.8xlarge which has 244 Gb of memory 上。显然这是一个极端的例子,但这个原则也适用于真实机器上的较小文件。
使用pd.read_csv
时,我的文件需要大约 30 分钟才能加载并占用 174Gb 的内存。基本上如此之多,以至于我无法用它做任何事情。相比之下,data.table
包中的 R 的 fread()
耗时约 7 分钟,内存仅为约 55Gb。
为什么 pandas 对象比 data.table 对象占用这么多内存?此外,为什么从根本上说 pandas 对象比磁盘上的文本文件大 10 倍?首先,.csv 并不是一种特别有效的数据存储方式。
【问题讨论】:
类似于https://***.com/questions/17444679/reading-a-huge-csv-file @RobertMc 不是熊猫 您使用的是fread
的 1.10.5,它是新的,在开发中,但尚未在 CRAN 上?也可以试试paratext。
@roganjosh fread
在开发(即 1.10.5)中要快得多,这就是我问的原因。不,我并不是说它阅读不正确。 OP 还询问速度和内存使用情况。
没错,我正在尝试将其加载到内存中以在其上运行 sklearn 模型。我从中获取的数据库输出了这个巨大的 .tsv,这就是我遇到这个问题的原因。没错,将其转换为另一种格式(hdf、parquet、feather 等)可能是最好的,我只是想让管道尽可能简单。旁注:使用 data.table 将其读取到 R,将其写入羽毛,然后将羽毛读入 Python 总共需要大约 12 分钟,而直接使用 pd.read_csv 到 Python 需要大约 30 分钟。这对我来说太疯狂了。
【参考方案1】:
您将无法超越 fread
的速度,但就内存使用而言,我的猜测是您的整数在 python 中被读取为 64 位整数。
假设您的文件如下所示:
a,b
1234567890123456789,12345
在 R 中,你会得到:
sapply(fread('test.txt'), class)
# a b
#"integer64" "integer"
而在 python 中(在 64 位机器上):
pandas.read_csv('test.txt').dtypes
#a int64
#b int64
因此,您将在 python 中使用更多内存。您可以强制输入read_csv
作为解决方法:
pandas.read_csv('test.txt', dtype='b': numpy.int32).dtypes
#a int64
#b int32
小整数也将成为 R 和 python 对象比 .csv 文件占用更多空间的原因,例如.csv 文件中的“1”占用 2 个字节(char + 逗号或行尾),但在内存中占用 4 或 8 个字节。
【讨论】:
我认为这可能是正确的。我从没想过在 read_csv 中使用dtype
选项。此外,我的很多列都是二进制的,但我敢打赌它也将所有这些 1 和 0 视为大整数。二进制(或非常小的)整数是否有有效的 numpy 类型,或者我应该只使用int32
?可能不会影响速度,但它绝对应该让它更小。谢谢。
您可以尝试使用int8
。
我会试试的。知道是否有办法说“这一列是 int64,所有其他列都是 int8”?文档说您必须将其作为 dict 来执行,但我有几千列(因此文件很大),所以这似乎有点乏味。
我可能只是阅读前几行,根据名称创建字典,然后阅读整个内容。
好电话。那一点也不难。谢谢。以上是关于将非常大的 CSV 数据集加载到 Python 和 R 中,Pandas 陷入困境的主要内容,如果未能解决你的问题,请参考以下文章
如何在 RNN TensorFlow 中使用非常大的数据集?
如何使用 Python 和 Pandas 创建比 RAM 更大的 csv 文件