在 Python 中将大量数字写入 HDF5 文件
Writing large amounts of numbers to a HDF5 file in Python
我目前有一个数据集,其中包含一百万行,每行大约 10000 列(可变长度)。
现在我想将此数据写入一个 HDF5 文件,以便以后使用。
我让它工作了,但是它慢得令人难以置信。即使是 1000 个值也需要几分钟才能存储到 HDF5 文件中。
我到处寻找,包括 SO 和 H5Py 文档,但我真的找不到任何描述我的用例的内容,但我知道它可以完成。
下面我制作了一个演示源代码来描述我现在正在做的事情:
import h5py
import numpy as np
# I am using just random values here
# I know I can use h5py broadcasts and I have seen it being used before.
# But the issue I have is that I need to save around a million rows with each 10000 values
# so I can't keep the entire array in memory.
random_ints = np.random.random(size = (5000,10000))
# See for "libver='latest'"
with h5py.File('my.data.hdf5', "w", libver='latest') as f:
X = f.create_dataset("X", (5000,10000))
for i1 in range(0, 5000):
for i2 in range(0, 10000):
X[i1,i2] = random_ints[i1,i2]
if i1 != 0 and i1 % 1000 == 0:
print "Done %d values..." % i1
此数据来自数据库,它不是预生成的 np 数组,如源代码中所示。
如果你 运行 这段代码你可以看到它需要很长时间才能打印出来 "Done 1000 values"。
我使用的笔记本电脑配备 8GB 内存、Ubuntu 16.04 LTS、Intel Core M(性能与 Core i5 类似)和 SSD,它们的性能一定足以比这快一点。
我在此处阅读过有关广播的信息:http://docs.h5py.org/en/latest/high/dataset.html
当我这样使用它时:
for i1 in range(0, 5000):
X[i1,:] = random_ints[i1]
它已经快了一个数量级(几秒钟就完成了)。但我不知道如何让它与可变长度数据集一起使用(列是可变长度的)。如果能对如何完成这项工作有一些了解,那将是很好的,因为我认为我现在对 HDF5 的概念还不是很了解:)非常感谢!
关注http://docs.h5py.org/en/latest/special.html
并使用打开的 h5 文件 f
,我试过:
dt = h5py.special_dtype(vlen=np.dtype('int32'))
vset=f.create_dataset('vset', (100,), dtype=dt)
一一设置元素:
vset[0]=np.random.randint(0,100,1000) # set just one element
for i in range(100): # set all arrays of varying length
vset[i]=np.random.randint(0,100,i)
vset[:] # view the dataset
或者创建对象数组:
D=np.empty((100,),dtype=object)
for i in range(100): # setting that in same way
D[i]=np.random.randint(0,100,i)
vset[:]=D # write it to the file
vset[:]=D[::-1] # or write it in reverse order
最后写的一部分:
In [587]: vset[-10:]
Out[587]:
array([array([52, 52, 46, 80, 5, 89, 6, 63, 21]),
array([38, 95, 51, 35, 66, 44, 29, 26]),
array([51, 96, 3, 64, 55, 31, 18]),
array([85, 96, 30, 82, 33, 45]), array([28, 37, 61, 57, 88]),
array([76, 65, 5, 29]), array([78, 29, 72]), array([77, 32]),
array([5]), array([], dtype=int32)], dtype=object)
我可以通过以下方式查看元素的一部分:
In [593]: vset[3][:10]
Out[593]: array([86, 26, 2, 79, 90, 67, 66, 5, 63, 68])
但我不能将其视为二维数组:vset[3,:10]
。这是一个数组数组。
我目前有一个数据集,其中包含一百万行,每行大约 10000 列(可变长度)。
现在我想将此数据写入一个 HDF5 文件,以便以后使用。 我让它工作了,但是它慢得令人难以置信。即使是 1000 个值也需要几分钟才能存储到 HDF5 文件中。
我到处寻找,包括 SO 和 H5Py 文档,但我真的找不到任何描述我的用例的内容,但我知道它可以完成。
下面我制作了一个演示源代码来描述我现在正在做的事情:
import h5py
import numpy as np
# I am using just random values here
# I know I can use h5py broadcasts and I have seen it being used before.
# But the issue I have is that I need to save around a million rows with each 10000 values
# so I can't keep the entire array in memory.
random_ints = np.random.random(size = (5000,10000))
# See for "libver='latest'"
with h5py.File('my.data.hdf5', "w", libver='latest') as f:
X = f.create_dataset("X", (5000,10000))
for i1 in range(0, 5000):
for i2 in range(0, 10000):
X[i1,i2] = random_ints[i1,i2]
if i1 != 0 and i1 % 1000 == 0:
print "Done %d values..." % i1
此数据来自数据库,它不是预生成的 np 数组,如源代码中所示。
如果你 运行 这段代码你可以看到它需要很长时间才能打印出来 "Done 1000 values"。
我使用的笔记本电脑配备 8GB 内存、Ubuntu 16.04 LTS、Intel Core M(性能与 Core i5 类似)和 SSD,它们的性能一定足以比这快一点。
我在此处阅读过有关广播的信息:http://docs.h5py.org/en/latest/high/dataset.html
当我这样使用它时:
for i1 in range(0, 5000):
X[i1,:] = random_ints[i1]
它已经快了一个数量级(几秒钟就完成了)。但我不知道如何让它与可变长度数据集一起使用(列是可变长度的)。如果能对如何完成这项工作有一些了解,那将是很好的,因为我认为我现在对 HDF5 的概念还不是很了解:)非常感谢!
关注http://docs.h5py.org/en/latest/special.html
并使用打开的 h5 文件 f
,我试过:
dt = h5py.special_dtype(vlen=np.dtype('int32'))
vset=f.create_dataset('vset', (100,), dtype=dt)
一一设置元素:
vset[0]=np.random.randint(0,100,1000) # set just one element
for i in range(100): # set all arrays of varying length
vset[i]=np.random.randint(0,100,i)
vset[:] # view the dataset
或者创建对象数组:
D=np.empty((100,),dtype=object)
for i in range(100): # setting that in same way
D[i]=np.random.randint(0,100,i)
vset[:]=D # write it to the file
vset[:]=D[::-1] # or write it in reverse order
最后写的一部分:
In [587]: vset[-10:]
Out[587]:
array([array([52, 52, 46, 80, 5, 89, 6, 63, 21]),
array([38, 95, 51, 35, 66, 44, 29, 26]),
array([51, 96, 3, 64, 55, 31, 18]),
array([85, 96, 30, 82, 33, 45]), array([28, 37, 61, 57, 88]),
array([76, 65, 5, 29]), array([78, 29, 72]), array([77, 32]),
array([5]), array([], dtype=int32)], dtype=object)
我可以通过以下方式查看元素的一部分:
In [593]: vset[3][:10]
Out[593]: array([86, 26, 2, 79, 90, 67, 66, 5, 63, 68])
但我不能将其视为二维数组:vset[3,:10]
。这是一个数组数组。