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 数据框保存到镶木地板文件是否可行?

  • 保存巨大的数据帧是否正常dask并且fastparquet需要这么长时间?

  • 有什么方法可以估计保存镶木地板文件所需的时间吗?

4

1 回答 1

16

正如上面评论中所讨论的,没有理论上的理由不.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)

或者放弃数据帧阶段可能会np.loadtxt更有效。dask.delayed

于 2017-05-31T18:18:04.293 回答