【问题标题】:Fastest way to write a file with h5py用 h5py 写文件的最快方法
【发布时间】:2014-08-17 17:18:33
【问题描述】:

首先,我阅读了主题“Fastest way to write hdf5 file with Python?”,但没有太大帮助。

我正在尝试在 h5f5 结构中加载大约 1GB 的文件(大小为 (70133351,1) 的矩阵)。

相当简单的代码,但速度很慢。

import h5py
f = h5py.File("8.hdf5", "w")
dset = f.create_dataset("8", (70133351,1))

myfile=open("8.txt")

for line in myfile:
   line=line.split("\t")
   dset[line[1]]=line[0]

myfile.close()
f.close()

我有一个50MB的小版本矩阵,我试了同样的代码,24小时后还是没写完。

我知道让它更快的方法是避免“for循环”。如果我使用的是常规 python,我会使用哈希理解。不过,这里好像不适合。

我稍后可以通过以下方式查询文件:

f = h5py.File("8.hdf5")
h=f['8']
print 'GFXVG' in h.attrs 

考虑到 GFXVG 在 h 中的键上,这会回答我“正确”

有人知道吗?

部分文件示例:

508 LREGASKW
592 SVFKINKS
1151        LGHWTVSP
131 EAGQIISE
198 ELDDSARE
344 SQAVAVAN
336 ELDDSARF
592 SVFKINKL
638 SVFKINKI
107 PRTGAGQH
107 PRTGAAAA

谢谢

【问题讨论】:

  • 从你是 quoting 的帖子中,“读取 [..] 以尽可能大的块”并写入 un 块。
  • 嗨,托尼。感谢您指出。你能给我举个例子吗?
  • 你能从文件 8.txt 中放几行数据吗?
  • 哦,@user3780518,刚刚看到你的评论。抱歉误读。 h5py 数据集是数组而不是哈希表。您可能希望在此处编写自己的哈希函数,该函数可以将这些 str 映射到 int,以便您可以索引到数据集。
  • h.attrs 将是一个字典,但不建议使用 attrs 作为数据集。 hdf5 中的数据集本质上可以被认为是 numpy 数组,我认为当前的方法存在一个根本问题。它适用于您的测试并不意味着它一定会起作用。

标签: python h5py


【解决方案1】:

我最终使用库搁置 (Pickle versus shelve storing large dictionaries in Python) 将大型字典存储到文件中。我花了 2 天时间才将哈希写入文件,但一旦完成,我就能够非常快速地加载和访问任何元素。归根结底,我不必阅读我的大文件并将所有信息写入其中,也不必对哈希做任何我想做的事情。

问题解决了!

【讨论】:

    【解决方案2】:

    既然只有一个gb,为什么不先把它完全加载到内存中呢?请注意,您似乎也在使用 str 对 dset 进行索引,这可能是问题所在。

    我刚刚意识到我误读了最初的问题,对此感到抱歉。看起来您的代码正在尝试使用似乎是字符串的索引 1 作为索引?可能有错别字?

    import h5py
    from numpy import zeros
    
    data = zeros((70133351,1), dtype='|S8') # assuming your strings are all 8 characters, use object if vlen
    
    with open('8.txt') as myfile: 
       for line in myfile:
           idx, item = line.strip().split("\t")
           data[int(line[0])] = line[1]
    
    with h5py.File('8.hdf5', 'w') as f:
        dset = f.create_dataset("8", (70133351, 1), data=data)
    

    【讨论】:

    • 感谢您的回答,丹尼尔。但是,我相信它不能解决我的问题。正如我上面所说,我需要第二列作为我的主键,而你这样做的方式是使用数字作为主键。这里的数字不能是主键,因为它们会重复(可能不在我给出的小例子中;我的错)。顺便说一句,它必须是 data[int(idx)] =item 而不是 data[int(line[1])] = line[0]
    • 我在顶部更新了我的问题。我相信现在更清楚了
    【解决方案3】:

    您可以使用loadtext 将所有数据加载到numpy array,并使用它来实例化您的hdf5 数据集。

    import h5py
    import numpy as np
    
    d = np.loadtxt('data.txt', dtype='|S18')
    

    返回

    array([['508.fna', 'LREGASKW'],
       ['592.fna', 'SVFKINKS'],
       ['1151.fna', 'LGHWTVSP'],
       ['131.fna', 'EAGQIISE'],
       ['198.fna', 'ELDDSARE'],
       ['344.fna', 'SQAVAVAN'],
       ['336.fna', 'ELDDSARF'],
       ['592.fna', 'SVFKINKL'],
       ['638.fna', 'SVFKINKI'],
       ['107.fna', 'PRTGAGQH'],
       ['1197.fna', 'ELDDSARR'],
       ['1309.fna', 'SQTIYVWF'],
       ['974.fna', 'PNNLRFIA'],
       ['230.fna', 'IGKVYHIE'],
       ['76.fna', 'PGVHSVWV'],
       ['928.fna', 'HERGGAND'],
       ['520.fna', 'VLKTDTTG'],
       ['1290.fna', 'EAALDLHR'],
       ['25.fna', 'FCSILGVV'],
       ['284.fna', 'YHKLTFED'],
       ['1110.fna', 'KITSSSDF']], 
      dtype='|S18')
    

    然后

    h = h5py.File('data.hdf5', 'w')
    dset = h.create_dataset('data', data=d)
    

    给出:

    <HDF5 dataset "init": shape (21, 2), type "|S18">
    

    【讨论】:

    • 我喜欢使用loadtxt,我总是忘记它。我认为在示例数据中,虽然 col 0 是 int,当然可以通过将预期的 dtypes 传递给 loadtxt 来进行管理。
    • 过程中数据格式明显改变了.. :)
    • 谢谢@toine,但是使用你的方法我无法像使用慢代码创建的结构那样查询我的数据。 f = h5py.File("5.hdf5") h=f['5'] print 'GFXVG' in h.attrs
    • 我在顶部更新了我的问题。我相信现在更清楚了
    猜你喜欢
    • 1970-01-01
    • 2011-07-24
    • 1970-01-01
    • 2013-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-19
    相关资源
    最近更新 更多