我有一个100M的行csv文件(实际上很多单独的csv文件)总共84GB。我需要将它转换为具有单个float数据集的HDF5文件。我在测试中使用了 h5py 而没有任何问题,但现在我无法在没有内存不足的情况下完成最终数据集。
如何在不必将整个数据集存储在内存中的情况下写入HDF5?我在这里期待实际代码,因为它应该非常简单。
我只是在研究 pytables ,但看起来不像数组类(对应于HDF5数据集)可以迭代编写。同样, pandas 在read_csv
中有to_hdf
和io_tools
个方法,但我无法一次加载整个数据集,因此无效。也许你可以帮我用pytables或pandas中的其他工具正确解决问题。
答案 0 :(得分:32)
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'))
产量
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
请注意,您需要在第一次调用format='table'
时使用df.to_hdf
才能使表格可附加。否则,默认情况下格式为'fixed'
,读取和写入速度更快,但会创建一个无法追加的表格。
因此,您可以一次处理一个CSV,使用append=True
构建hdf5文件。然后覆盖DataFrame或使用del df
允许旧的DataFrame被垃圾收集。
或者,您可以append to a HDFStore:
而不是致电df.to_hdf
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()
产量
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
答案 1 :(得分: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)))
查看文档以获取详细说明,但非常简单地说,create_earray
函数需要1)数据根节点或父节点; 2)数组名称; 3)数据类型原子; 4)要扩展的维度中具有0
的形状; 5)详细的描述符; 6)a compression filter; 7)沿可扩展维度的预期行数。只需要前两个,但你可能会在实践中使用全部七个。该函数也接受一些其他可选参数;再次,请参阅文档了解详情。
创建数组后,您可以按预期方式使用其append
方法。