将一个大的dask dataframe保存为parquet格式是否可行?

17

我有一个数据框,由100,000+行组成,每行有100,000列,共计10,000,000,000个浮点值。

之前我已经成功将它们读入一个 csv(以制表符分隔)文件中,并在一台拥有250GB RAM的50核Xeon机器上成功读取并尝试将其写出为一个 .parq 目录,如下所示:

huge.csv 中的浮点数被保存为字符串,大小为125GB。

import dask.dataframe as dd
filename = 'huge.csv'
df = dd.read_csv(filename, delimiter='\t', sample=500000000)
df.to_parquet('huge.parq')

已经有一周的时间在向 huge.parq 写入数据,目录大小为14GB,保存 .to_parquet 的过程似乎不会很快结束。

free -mh 显示还有可用内存,但保存 .parq 目录所需的时间非常慢:

$ free -mh
              total        used        free      shared  buff/cache   available
Mem:           251G         98G         52G         10M        101G        152G
Swap:          238G          0B        238G

以下是需要翻译的内容:

  • 考虑到数据帧的大小和机器性能,将dask数据帧保存为parquet文件是否可行?

  • dask和fastparquet保存大型数据帧需要这么长时间是正常的吗?

  • 有没有一种方法可以估计保存parquet文件所需的时间?


10亿个浮点数对我来说似乎不算太大,但是1万个列确实很大。您考虑过使用dask.array和HDF5吗?这些可能更适合在两个维度上进行分块。 - MRocklin
1
dask.array和HDF5对于具有大量列的数据框更好的原因是什么?“blocking”是什么意思? - alvas
每个分区有多少行?read_csv按字节数拆分,因此我期望数量很少。对于每个分区的每个列,都必须存在单独的元数据片段,使得您的元数据比我以前见过的任何元数据都要大 - 但我希望它能够正常工作。对于存储类似数组的100kx100k浮点数,我实际上建议使用[zarr](http://zarr.readthedocs.io/en/latest/)。 - mdurant
Parquet 为每个列创建一个新的数据段,因此每个列都具有非平凡的成本。HDF5 或 ZArr 可以按行和列“分块”或分组数据。如果您有许多行和许多列,则这往往更好。 - MRocklin
1个回答

17

如上方评论所述,.to_parquet() 没有理论上的限制无法处理您的数据。然而,由于列数非常大,每个列都有一定的开销,因此处理过程需要花费很长时间 - 这不是典型的使用情况。

您的数据最好被视为一个数组而不是表格。有一些数组存储机制可以让您在每个维度上进行分块,例如zarr,它还允许进行各种压缩和预过滤操作,能够高效利用磁盘空间。(像HDF5这样的其他格式也很适合这种任务)

以下是存储一个10k x 10k数组的示例:

import dask.array as da
import zarr
arr = da.random.random(size=(10000, 10000), chunks=(1000, 1000))
z = zarr.open_array('z.zarr', shape=(10000, 10000), chunks=(1000, 1000), mode='w', dtype='float64')
arr.store(z)

现在z.zarr/包含100个数据文件块。

在您的情况下,棘手的部分是读取数据,因为您不事先知道行数。您可以使用

df = dataframe.read_csv(..)
len(df)  # get length
z = zarr.open_arr(...)  # provide dtype, size and chunk appropriately
df.values.store(z)

或者更高效的方法是使用dask.delayed包装np.loadtxt,跳过数据框架阶段。


1
有一些数据集,例如KDD-2009(http://www.kdd.org/kdd-cup/view/kdd-cup-2009/Data),它有15,000列和50,000条记录。虽然它不是100,000乘以100,000的矩阵,但它是一个列式数据集,因此将其处理为矩阵没有任何意义。您是否知道Dask DataFrame的限制? - Vlad Frolov
2
我认为没有特定的限制,但是你为各种计算所支付的开销取决于你试图做什么。我很想看到所有数据存储为Parquet的性能(使用合理的列数据类型选择)。 - mdurant

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接