afs*_*hin 1 python hdf5 pytables h5py pandas
我有一系列包含大熊猫数据帧的 hdf5 文件。一个典型的文件大约有 1000,000 行。我使用 complib='blosc',complevel=9 进行压缩。原始 hdf5 文件保存为 1 个平面文件。
然后,我尝试将数据帧逻辑分割为 30 个较小的数据帧,并将它们保存在具有 30 个不同键和相同压缩的同一个 hdf5 文件中。
令人震惊的问题是,具有 30 个较小数据帧的文件比平面文件大 40 倍。
平面 hdf5 文件保存如下:
dfx.to_hdf(file_name, key='opp',mode='a',complib='blosc',complevel=9, append=True)
分段的hdf5文件保存如下:
for i in range(30): dfx_small[i].to_hdf(file_name,key='d'+str(i), mode='a',complib='blosc',complevel=9
我做错了什么或者这个尺寸增加是预期的吗?
我比较了生成为 1) 平面数据帧与 2)30 块数据帧的所有 hdf5 文件 - 当数据帧保存为 30 个较小的数据帧时,最大的文件大小似乎增加了 8 倍到 10 倍,同时较小的文件大小增加了 100 倍到 1000 倍。然后我尝试在压缩和不压缩的情况下保存 30 个块的 hdf5 文件。看来,当多个具有唯一键的数据帧放置在同一个 hdf5 文件中时,压缩几乎不起作用。我尝试了所有压缩选项,结果相似。
保存具有多个数据集的 hdf5 文件时存在压缩错误。
我添加了问题#45286
我创建了一些简单的测试,并发现了一些有趣的行为。
complib='blosc',complevel=9. 正如预期的那样,未压缩的文件更大,但从 1 个 DF 到 30 个 DF 的增加要低得多(仅增加 65%)。熊猫结果
| DF 数量 | 压缩 | 大小(MB) |
|---|---|---|
| 1 | 布洛斯-9 | 3.1 |
| 30 | 布洛斯-9 | 33.5 |
| 1 | 不 | 24.8 |
| 30 | 不 | 54.8 |
因此,某些行为可能是由于多个较小数据帧的压缩差异造成的。(压缩可能不那么有效。)此外,Pandas 使用“有趣的”模式来存储数据帧。如果您使用 HDF View 检查文件,数据看起来不像表格(就像您使用 PyTables 或 h5py 保存数据时看到的那样)。当您有多个数据帧时,可能会出现重复的开销(但这只是一个推论)。
2021-01-08 更新:
您还可以使用PyTables或保存为 HDF5 格式h5py。(Pandas 构建在 PyTables 之上。)出于好奇,我扩展了上面的示例,用每个包编写 HDF5 文件。一个文件有一个数据集,另一个文件有 30 个数据集(模仿数据帧方法)。我还比较了压缩的效果。结果提供了有趣的见解。
PyTables 结果
| DS 数量 | 压缩 | 大小(MB) |
|---|---|---|
| 1 | 布洛斯-9 | 0.14 |
| 30 | 布洛斯-9 | 0.40 |
| 1 | Zlib-9 | 0.08 |
| 30 | Zlib-9 | 0.17 |
| 1 | 不 | 11.9 |
| 30 | 不 | 13.5 |
Pandas 与 PyTables 观察
h5py 结果
| DS 数量 | 压缩 | 大小(MB) |
|---|---|---|
| 1 | Gzip-9 | 0.15 |
| 30 | Gzip-9 | 0.40 |
| 1 | 不 | 11.9 |
| 30 | 不 | 11.9 |
Pandas 与 h5py 观察
PyTables 与 h5py 观察结果
创建测试数据(作为列表):
import string
col1 = list(string.ascii_letters)
col2 = [ x for x in range(1,53)]
col3 = [ float(x) for x in range(1,53)]
ncopies = 18_000
nslices = 30
fact = len(col1)*ncopies//nslices
col_c = []; col_int = []; col_float = []
for i in range(ncopies):
col_c.extend(col1)
col_int.extend(col2)
col_float.extend(col3)
Run Code Online (Sandbox Code Playgroud)
用 Pandas 写入测试数据:
import pandas as pd
dfx = pd.DataFrame({'col_c': col_c, 'col_int': col_int, 'col_float': col_float})
dfx.to_hdf('pd_file_1_blosc.h5',key='test_data',mode='a',complib='blosc',complevel=9)
dfx.to_hdf('pd_file_1_uc.h5',key='test_data',mode='a')
for i in range(nslices):
dfx_small = dfx[i*fact:(i+1)*fact]
dfx_small.to_hdf('pd_file_30_blosc.h5',key=f'd{i:02}', mode='a',complib='blosc',complevel=9)
dfx_small.to_hdf('pd_file_30_uc.h5',key=f'd{i:02}', mode='a')
Run Code Online (Sandbox Code Playgroud)
为 PyTables 和 h5py 创建 NumPy rearray:
import numpy as np
arr_dt = np.dtype([ ('col_c', 'S1'), ('col_int', int), ('col_float', float) ])
recarr = np.empty(shape=(len(col_c),), dtype=arr_dt)
recarr['col_c'] = col_c
recarr['col_int'] = col_int
recarr['col_float'] = col_float
Run Code Online (Sandbox Code Playgroud)
使用 PyTables 写入测试数据:
import tables as tb
f_blosc = tb.Filters(complib ="blosc", complevel=9)
f_zlib = tb.Filters(complib ="zlib", complevel=9)
with tb.File('tb_file_1_blosc.h5','w') as h5f:
h5f.create_table('/','test_data', obj=recarr, filters=f_blosc)
with tb.File('tb_file_1_zlib.h5','w') as h5f:
h5f.create_table('/','test_data', obj=recarr, filters=f_zlib)
with tb.File('tb_file_1_uc.h5','w') as h5f:
h5f.create_table('/','test_data', obj=recarr)
with tb.File('tb_file_30_blosc.h5','w') as h5f:
for i in range(nslices):
h5f.create_table('/',f'test_data_{i:02}', obj=recarr[i*fact:(i+1)*fact],
filters=f_blosc)
with tb.File('tb_file_30_zlib.h5','w') as h5f:
for i in range(nslices):
h5f.create_table('/',f'test_data_{i:02}', obj=recarr[i*fact:(i+1)*fact],
filters=f_zlib)
with tb.File('tb_file_30_uc.h5','w') as h5f:
for i in range(nslices):
h5f.create_table('/',f'test_data_{i:02}', obj=recarr[i*fact:(i+1)*fact])
Run Code Online (Sandbox Code Playgroud)
用h5py写入测试数据:
import h5py
with h5py.File('h5py_file_1_gzip.h5','w') as h5f:
h5f.create_dataset('test_data', data=recarr, compression="gzip", compression_opts=9)
with h5py.File('h5py_file_1_uc.h5','w') as h5f:
h5f.create_dataset('test_data', data=recarr)
with h5py.File('h5py_file_30_gzip.h5','w') as h5f:
for i in range(nslices):
h5f.create_dataset(f'test_data_{i:02}', data=recarr[i*fact:(i+1)*fact],
compression="gzip", compression_opts=9)
with h5py.File('h5py_file_30_uc.h5','w') as h5f:
for i in range(nslices):
h5f.create_dataset(f'test_data_{i:02}', data=recarr[i*fact:(i+1)*fact])
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2100 次 |
| 最近记录: |