是否可以将巨大的 dask 数据框保存到镶木地板中?

Posted

技术标签:

【中文标题】是否可以将巨大的 dask 数据框保存到镶木地板中?【英文标题】:Is saving a HUGE dask dataframe into parquet possible? 【发布时间】:2017-10-26 22:29:50 【问题描述】:

我有一个由 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 文件是否可行?

daskfastparquet 需要这么长时间来保存大量数据帧是否正常?

有什么方法可以估算保存 parquet 文件所需的时间吗?

【问题讨论】:

10e9 浮点值对我来说似乎并不大。 1e5 列虽然可以。您是否考虑过使用 dask.array 和 HDF5?这些可能更适合在两个维度上进行屏蔽。 dask.array 和 HDF5 是否更适合 >>> 否的数据帧。列?什么是“阻塞”? 每个分区有多少行? read_csv 按字节数拆分,所以我希望数量很少。对于每个分区的每一列,必须存在一个单独的元数据,这使您的元数据比我以前见过的任何元数据都大——但我希望它能够工作。对于存储类似数组的 100kx100k 浮点数,我实际上推荐zarr。 Parquet 为每一列创建一个新的数据段。所以每一列都有不小的成本。 HDF5 或 ZArr 可以按行和按列“阻止”或分组数据。如果您有很多行和很多列,这往往会更好 【参考方案1】:

正如上面 cmets 中所讨论的,.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 以放弃数据帧阶段可能更有效。

【讨论】:

有像 KDD-2009 (kdd.org/kdd-cup/view/kdd-cup-2009/Data) 这样的数据集,它有 15k 列和 50k 条记录。它不是 100k x 100k,而是列式数据集,因此将其作为矩阵处理没有任何意义。你知道 Dask DataFrame 的局限性吗? 我会说没有特别的限制,但是您为各种计算支付的间接费用将取决于您要执行的操作。我很想看看存储为 parquet 的所有数据的性能(合理选择列数据类型)。

以上是关于是否可以将巨大的 dask 数据框保存到镶木地板中?的主要内容,如果未能解决你的问题,请参考以下文章

无法将数据框保存到镶木地板 pyspark

将rdd保存到镶木地板文件scala

带有 hive 的 pyspark - 无法正确创建分区并从数据框中保存表

是否可以从 Dask 读取镶木地板元数据?

无法将数据附加到镶木地板 [FileAlreadyExists 异常]

覆盖和附加到镶木地板有啥区别