将大型csv转换为hdf5

jmi*_*loy 26 python csv hdf5 pytables pandas

我有一个100M行csv文件(实际上很多单独的csv文件)总共84GB.我需要将它转换为具有单个float数据集的HDF5文件.我在测试中使用了h5py而没有任何问题,但是现在我不能在没有内存耗尽的情况下完成最终的数据集.

如何在不必将整个数据集存储在内存中的情况下写入HDF5?我在这里期待实际代码,因为它应该非常简单.

我只是在研究pytables,但它看起来不像数组类(对应于HDF5数据集)可以迭代编写.同样,熊猫拥有read_csvto_hdf在它的方法io_tools,但我不能在同一时间加载整个数据集,这样将无法正常工作.也许你可以帮我用pytables或pandas中的其他工具正确解决问题.

unu*_*tbu 33

用于append=True致电to_hdf:

import numpy as np
import pandas as pd

filename = '/tmp/test.h5'

df = pd.DataFrame(np.arange(10).reshape((5,2)), columns=['A', 'B'])
print(df)
#    A  B
# 0  0  1
# 1  2  3
# 2  4  5
# 3  6  7
# 4  8  9

# Save to HDF5
df.to_hdf(filename, 'data', mode='w', format='table')
del df    # allow df to be garbage collected

# Append more data
df2 = pd.DataFrame(np.arange(10).reshape((5,2))*10, columns=['A', 'B'])
df2.to_hdf(filename, 'data', append=True)

print(pd.read_hdf(filename, 'data'))
Run Code Online (Sandbox Code Playgroud)

产量

    A   B
0   0   1
1   2   3
2   4   5
3   6   7
4   8   9
0   0  10
1  20  30
2  40  50
3  60  70
4  80  90
Run Code Online (Sandbox Code Playgroud)

请注意,您需要format='table'在第一次调用时使用df.to_hdf以使表可附加.否则,'fixed'默认格式为读取和写入更快,但会创建一个无法追加的表格.

因此,您可以一次处理一个CSV,用于append=True构建hdf5文件.然后覆盖DataFrame或用于del df允许旧的DataFrame被垃圾收集.


或者,df.to_hdf您可以附加到HDFStore而不是调用:

import numpy as np
import pandas as pd

filename = '/tmp/test.h5'
store = pd.HDFStore(filename)

for i in range(2):
    df = pd.DataFrame(np.arange(10).reshape((5,2)) * 10**i, columns=['A', 'B'])
    store.append('data', df)

store.close()

store = pd.HDFStore(filename)
data = store['data']
print(data)
store.close()
Run Code Online (Sandbox Code Playgroud)

产量

    A   B
0   0   1
1   2   3
2   4   5
3   6   7
4   8   9
0   0  10
1  20  30
2  40  50
3  60  70
4  80  90
Run Code Online (Sandbox Code Playgroud)


sen*_*rle 6

PyTables应该可以实现这一点.但是你需要使用EArray类.

例如,以下是我编写的脚本,用于将作为.npy文件存储的分块训练数据导入单个.h5文件中.

import numpy
import tables
import os

training_data = tables.open_file('nn_training.h5', mode='w')
a = tables.Float64Atom()
bl_filter = tables.Filters(5, 'blosc')   # fast compressor at a moderate setting

training_input =  training_data.create_earray(training_data.root, 'X', a,
                                             (0, 1323), 'Training Input',
                                             bl_filter, 4000000)
training_output = training_data.create_earray(training_data.root, 'Y', a,
                                             (0, 27), 'Training Output',
                                             bl_filter, 4000000)

for filename in os.listdir('input'):
    print "loading {}...".format(filename)
    a = numpy.load(os.path.join('input', filename))
    print "writing to h5"
    training_input.append(a)

for filename in os.listdir('output'):
    print "loading {}...".format(filename)
    training_output.append(numpy.load(os.path.join('output', filename)))
Run Code Online (Sandbox Code Playgroud)

请查看文档以获取详细说明,但非常简单地说,该create_earray函数需要1)数据根或父节点; 2)数组名称; 3)数据类型原子; 4)具有0要扩展的尺寸的形状; 5)详细的描述符; 6)压缩过滤器 ; 7)沿可扩展维度的预期行数.只需要前两个,但你可能会在实践中使用全部七个.该函数也接受一些其他可选参数; 再次,请参阅文档了解详细信息.

创建数组后,您可以append按预期方式使用其方法.