将非常大的 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 中使用非常大的数据集?

解析一个非常大的 CSV 数据集

如何使用 Python 和 Pandas 创建比 RAM 更大的 csv 文件

如何读取非常大的 CSV 的一小部分行。 Pandas - 时间序列 - 大型数据集

删除非常大的数据集上的重复项

将没有数字 ID 的非常大的表从 MySQL 加载到 S3