我有一个由100,000多行组成的数据帧,每行有100,000列,总共10,000,000,000个浮点值。
我之前在csv
(制表符分隔)文件中设法读取它们,然后我成功地将它们读取到具有250GB RAM的50核Xeon机器并尝试将其写为{{1这样的目录:
.parq
中的浮点数保存为字符串,为125GB。
huge.csv
它已写入import dask.dataframe as dd
filename = 'huge.csv'
df = dd.read_csv(filename, delimiter='\t', sample=500000000)
df.to_parquet('huge.parq')
近一周,目录为14GB,似乎保存huge.parq
的过程不会很快停止。
并且.to_parquet
显示仍有内存可用但是保存free -mh
目录所花费的时间非常慢:
.parq
问题是:
考虑到数据帧和机器的大小,将dask数据帧保存到镶木地板文件是否可行?
$ free -mh
total used free shared buff/cache available
Mem: 251G 98G 52G 10M 101G 152G
Swap: 238G 0B 238G
和dask
花费这么长时间保存庞大的数据帧是否正常?
有没有办法估算保存镶木地板文件所需的时间?
答案 0 :(得分:11)
正如上面的评论中所讨论的,没有理论上的理由.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
一起包裹以放弃数据帧阶段可能更有效。