首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将多节点PyTable转换为bcolz

将多节点PyTable转换为bcolz
EN

Stack Overflow用户
提问于 2015-10-17 05:33:22
回答 1查看 325关注 0票数 0

我正在尝试使用bcolz,看看它是否与我需要做的事情兼容。我有一个由大约1100万行和大约120列组成的数据集。此数据当前以HDF5文件中的PyTables“表”格式存储。在HDF5文件中,数据被分成几个“组”(独立的节点),每个组包含不同的列。

我想要做的是将所有这些数据转换为磁盘上的bcolz ctable,而不是一次性将其全部读取到内存中。我可以通过这样对第一个组执行此操作(basic是其中一个组的名称):

代码语言:javascript
复制
bcolz.ctable.fromhdf5('census.h5', '/basic/table', rootdir='census')

当我这样做时,内存使用率仍然很低,这表明它不是一次读取整个表。太棒了!但是,如果我再次尝试这样做,将其附加到相同的ctable:

代码语言:javascript
复制
>>> bcolz.ctable.fromhdf5('census.h5', '/political/table', rootdir='census', mode='a')
Traceback (most recent call last):
  File "<pyshell#34>", line 1, in <module>
    bcolz.ctable.fromhdf5('census.h5', '/political/table', rootdir='census', mode='a')
  File "C:\FakeProgs\Python27\lib\site-packages\bcolz\ctable.py", line 714, in fromhdf5
    ct = ctable(cols, names, **kwargs)
  File "C:\FakeProgs\Python27\lib\site-packages\bcolz\ctable.py", line 205, in __init__
    "You cannot pass a `columns` param in 'a'ppend mode.\n"
ValueError: You cannot pass a `columns` param in 'a'ppend mode.
(If you are trying to create a new ctable, perhaps the directory exists already.)

是的,它当然已经存在了。bcolz的优点之一应该是很容易添加新列。如何利用这一优势将现有HDF5文件中的新列直接添加到现有的磁盘ctable中,而不必先将所有新列读取到内存中?

EN

回答 1

Stack Overflow用户

发布于 2015-10-21 20:53:19

一种想法是利用这样一个事实:在向ctable添加列时,如果该列是现有的carray,则可以请求移动磁盘上的文件(这是立即的),而不是复制它。因此,您可以首先为hdf5表的每一列创建一个数组,然后将其添加到ctable中。

请参阅下面的代码以了解大致方向。它的灵感来自how bcolz create a table from a hdf5 file,并且没有经过测试:

代码语言:javascript
复制
table = bcolz.ctable.fromhdf5('census.h5', '/basic/table', rootdir='census')

fp = tables.open_file('census.h5')
h5table = fp.get_node('/political/table')
for colname in h5table.colnames:
    h5column = h5table.colinstances[colname]
    #create the column
    coltype = h5table.coldtypes[colname]
    nparr = np.zeros(0, dtype=coltype)
    column = bcolz.carray(nparr, mode='w', rootdir='tmpcol')

    #Fill it in chunks
    chunklen = h5table._v_chunkshape[0]
    for i in xrange(0, len(h5table), chunklen):
        column.append(h5column[i:i+chunklen])
    column.flush()

    #Add column to table without copying
    table.addcol(column, name=colname, move=True)

我同意在blocz中有这个功能是很好的,但是我猜这个包还很年轻。也许您可以添加它!:)还要注意,在将数据存储到bcolz表中之前,数据将被读取到内存中。但它将只被读取一次,并且是分块的,这与您首先从h5文件在内存中创建表,然后他们将列复制到第一个表中的情况不同。我猜这就是你对without reading all the new columns into memory的意思。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33179895

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档