我可以使用 h5py 在一行中将字符串写入 HDF5 文件,而不是遍历条目吗?
Can I use h5py to write strings to an HDF5 file in one line, rather than looping over entries?
我需要使用 h5py
在 HDF5 文件中存储 list/array 个字符串。这些字符串是可变长度的。按照我在网上找到的示例,我有一个有效的脚本。
import h5py
h5File=h5py.File('outfile.h5','w')
data=['this','is','a','sentence']
dt = h5py.special_dtype(vlen=str)
dset = h5File.create_dataset('words',(len(data),1),dtype=dt)
for i,word in enumerate(data):
dset[i] = word
h5File.flush()
h5File.close()
但是,当 data
变得非常大时,写入会花费很长时间,因为它会遍历每个条目并将其插入到文件中。
我认为我可以在一行中完成所有操作,就像使用整数或浮点数一样。但是下面的脚本失败了。请注意,我添加了一些代码来测试 int
是否有效。
import h5py
h5File=h5py.File('outfile.h5','w')
data_numbers = [0, 1, 2, 3, 4]
data = ['this','is','a','sentence']
dt = h5py.special_dtype(vlen=str)
dset_num = h5File.create_dataset('numbers',(len(data_numbers),1),dtype=int,data=data_numbers)
print("Created the dataset with numbers!\n")
dset_str = h5File.create_dataset('words',(len(data),1),dtype=dt,data=data)
print("Created the dataset with strings!\n")
h5File.flush()
h5File.close()
该脚本给出以下输出。
Created the dataset with numbers!
Traceback (most recent call last):
File "write_strings_to_HDF5_file.py", line 32, in <module>
dset_str = h5File.create_dataset('words',(len(data),1),dtype=dt,data=data)
File "/opt/anaconda3/lib/python3.7/site-packages/h5py/_hl/group.py", line 136, in create_dataset
dsid = dataset.make_new_dset(self, shape, dtype, data, **kwds)
File "/opt/anaconda3/lib/python3.7/site-packages/h5py/_hl/dataset.py", line 170, in make_new_dset
dset_id.write(h5s.ALL, h5s.ALL, data)
File "h5py/_objects.pyx", line 54, in h5py._objects.with_phil.wrapper
File "h5py/_objects.pyx", line 55, in h5py._objects.with_phil.wrapper
File "h5py/h5d.pyx", line 211, in h5py.h5d.DatasetID.write
File "h5py/h5t.pyx", line 1652, in h5py.h5t.py_create
File "h5py/h5t.pyx", line 1713, in h5py.h5t.py_create
TypeError: No conversion path for dtype: dtype('<U8')
我已经阅读了有关 UTF-8 编码的文档并尝试了上述语法的多种变体,但我似乎遗漏了一些关键点。也许做不到?
感谢任何有建议的人!
如果有人想看到运行示例的减速,这里有一个测试用例。
import h5py
h5File=h5py.File('outfile.h5','w')
sentence=['this','is','a','sentence']
data = []
for i in range(10000):
data += sentence
print(len(data))
dt = h5py.special_dtype(vlen=str)
dset = h5File.create_dataset('words',(len(data),1),dtype=dt)
for i,word in enumerate(data):
dset[i] = word
h5File.flush()
h5File.close()
一次写入 1 行数据是写入 HDF5 文件的最慢方式。当您写入 100 行时您不会注意到性能问题,但随着行数的增加您会看到它。还有另一个答案讨论了这个问题。请参阅:pytables writes much faster than h5py. Why?(注意:我不建议您使用 PyTables
。链接的答案显示了 h5py
和 PyTables
的性能)。可以看到,写很多small chunks的时候写同样的数据量要长很多。
为了提高性能,您需要每次写入更多的数据。由于您已将所有数据加载到列表 data
中,因此您可以一次性完成。对于 10,000 行,它几乎是瞬时的。评论中引用的答案涉及这种技术(从列表数据创建 np.array()
。但是,它适用于小列表(1/行)......所以不完全相同。你必须小心你创建数组。你不能使用 NumPy 的默认 Unicode dtype——h5py
不支持它。相反,你需要 dtype='S#'
下面的代码显示将您的字符串列表转换为 np.array()
字符串。此外,我强烈建议您使用 Python 的 with/as:
联系人管理器打开该文件。这避免了文件由于意外退出(由于崩溃或逻辑错误)而意外保持打开状态的情况。
代码如下:
import h5py
import numpy as np
sentence=['this','is','a','sentence']
data = []
for i in range(10_000):
data += sentence
print(len(data))
longest_word=len(max(data, key=len))
print('longest_word=',longest_word)
dt = h5py.special_dtype(vlen=str)
arr = np.array(data,dtype='S'+str(longest_word))
with h5py.File('outfile.h5','w') as h5File:
dset = h5File.create_dataset('words',data=arr,dtype=dt)
print(dset.shape, dset.dtype)
我需要使用 h5py
在 HDF5 文件中存储 list/array 个字符串。这些字符串是可变长度的。按照我在网上找到的示例,我有一个有效的脚本。
import h5py
h5File=h5py.File('outfile.h5','w')
data=['this','is','a','sentence']
dt = h5py.special_dtype(vlen=str)
dset = h5File.create_dataset('words',(len(data),1),dtype=dt)
for i,word in enumerate(data):
dset[i] = word
h5File.flush()
h5File.close()
但是,当 data
变得非常大时,写入会花费很长时间,因为它会遍历每个条目并将其插入到文件中。
我认为我可以在一行中完成所有操作,就像使用整数或浮点数一样。但是下面的脚本失败了。请注意,我添加了一些代码来测试 int
是否有效。
import h5py
h5File=h5py.File('outfile.h5','w')
data_numbers = [0, 1, 2, 3, 4]
data = ['this','is','a','sentence']
dt = h5py.special_dtype(vlen=str)
dset_num = h5File.create_dataset('numbers',(len(data_numbers),1),dtype=int,data=data_numbers)
print("Created the dataset with numbers!\n")
dset_str = h5File.create_dataset('words',(len(data),1),dtype=dt,data=data)
print("Created the dataset with strings!\n")
h5File.flush()
h5File.close()
该脚本给出以下输出。
Created the dataset with numbers!
Traceback (most recent call last):
File "write_strings_to_HDF5_file.py", line 32, in <module>
dset_str = h5File.create_dataset('words',(len(data),1),dtype=dt,data=data)
File "/opt/anaconda3/lib/python3.7/site-packages/h5py/_hl/group.py", line 136, in create_dataset
dsid = dataset.make_new_dset(self, shape, dtype, data, **kwds)
File "/opt/anaconda3/lib/python3.7/site-packages/h5py/_hl/dataset.py", line 170, in make_new_dset
dset_id.write(h5s.ALL, h5s.ALL, data)
File "h5py/_objects.pyx", line 54, in h5py._objects.with_phil.wrapper
File "h5py/_objects.pyx", line 55, in h5py._objects.with_phil.wrapper
File "h5py/h5d.pyx", line 211, in h5py.h5d.DatasetID.write
File "h5py/h5t.pyx", line 1652, in h5py.h5t.py_create
File "h5py/h5t.pyx", line 1713, in h5py.h5t.py_create
TypeError: No conversion path for dtype: dtype('<U8')
我已经阅读了有关 UTF-8 编码的文档并尝试了上述语法的多种变体,但我似乎遗漏了一些关键点。也许做不到?
感谢任何有建议的人!
如果有人想看到运行示例的减速,这里有一个测试用例。
import h5py
h5File=h5py.File('outfile.h5','w')
sentence=['this','is','a','sentence']
data = []
for i in range(10000):
data += sentence
print(len(data))
dt = h5py.special_dtype(vlen=str)
dset = h5File.create_dataset('words',(len(data),1),dtype=dt)
for i,word in enumerate(data):
dset[i] = word
h5File.flush()
h5File.close()
一次写入 1 行数据是写入 HDF5 文件的最慢方式。当您写入 100 行时您不会注意到性能问题,但随着行数的增加您会看到它。还有另一个答案讨论了这个问题。请参阅:pytables writes much faster than h5py. Why?(注意:我不建议您使用 PyTables
。链接的答案显示了 h5py
和 PyTables
的性能)。可以看到,写很多small chunks的时候写同样的数据量要长很多。
为了提高性能,您需要每次写入更多的数据。由于您已将所有数据加载到列表 data
中,因此您可以一次性完成。对于 10,000 行,它几乎是瞬时的。评论中引用的答案涉及这种技术(从列表数据创建 np.array()
。但是,它适用于小列表(1/行)......所以不完全相同。你必须小心你创建数组。你不能使用 NumPy 的默认 Unicode dtype——h5py
不支持它。相反,你需要 dtype='S#'
下面的代码显示将您的字符串列表转换为 np.array()
字符串。此外,我强烈建议您使用 Python 的 with/as:
联系人管理器打开该文件。这避免了文件由于意外退出(由于崩溃或逻辑错误)而意外保持打开状态的情况。
代码如下:
import h5py
import numpy as np
sentence=['this','is','a','sentence']
data = []
for i in range(10_000):
data += sentence
print(len(data))
longest_word=len(max(data, key=len))
print('longest_word=',longest_word)
dt = h5py.special_dtype(vlen=str)
arr = np.array(data,dtype='S'+str(longest_word))
with h5py.File('outfile.h5','w') as h5File:
dset = h5File.create_dataset('words',data=arr,dtype=dt)
print(dset.shape, dset.dtype)