将ndarray存储在PyTable中(以及如何定义Col() - 类型)

时间:2018-03-12 10:14:40

标签: python arrays numpy pytables

TL; DR :我有一个带有float32 Col的PyTable,并在写入numpy-float32-array时出错。 (如何)我可以在PyTables表的列中存储numpy-array(float32)?

我是PyTables的新手 - 按照TFtables(在Tensorflow中使用HDF5的lib)的推荐,我用它来存储我的所有HDF5数据(目前分批分发)单个HDF5文件中的表中的每个三个数据集的几个文件。数据集是

'data' : (n_elements, 1024, 1024, 4)@float32
'label' : (n_elements, 1024, 1024, 1)@uint8
'weights' : (n_elements, 1024, 1024, 1)@float32

其中n_elements分布在我想要合并为一个文件的几个文件中(允许无序访问)。

因此,当我构建表时,我认为每个数据集代表一个列。我以通用的方式构建了所有内容,允许为任意数量的数据集执行此操作:

# gets dtypes (and shapes) of the dsets (accessed by dset_keys = ['data', 'label', 'weights']
dtypes, shapes = _determine_shape(hdf5_files, dset_keys)

# to dynamically generate a table, I'm using a dict (not a class as in the PyTables tutorials)
# the dict is (conform with the doc): { 'col_name' : Col()-class-descendent }
table_description = {dset_keys[i]: tables.Col.from_dtype(dtypes[i]) for i in range(len(dset_keys))}

# create a file, a group-node and attach a table to it
h5file = tables.open_file(destination_file, mode="w", title="merged")
group = h5file.create_group("/", 'main', 'Node for data table')
table = h5file.create_table(group, 'data_table', table_description, "Collected data with %s" % (str(val_keys)))

我为每个dsets获取的dtypes(使用h5py读取)显然是读取dset的numpy数组(ndarray)返回的:float32uint8。所以Col() - 类型是Float32ColUInt8Col。我天真地假设我现在可以在这个col中编写一个float32数组,但用以下内容填充数据:

dummy_data = np.zeros([1024,1024,3], float32) # normally data read from other files

sample = table.row
sample['data'] = dummy_data

结果为TypeError: invalid type (<class 'numpy.ndarray'>) for column ``data``。所以现在我觉得我能够在那里写一个数组感觉很愚蠢,但是没有&#34; ArrayCol()&#34;提供的类型,PyTables doc中是否有任何关于是否或如何将数组写入列的提示。我该怎么做?

有&#34;形状&#34; Col()类中的参数及其后代,所以它应该是可能的,否则这些是什么?!

2 个答案:

答案 0 :(得分:0)

编辑: 我刚看到tables.Col.from_type(type, shape)允许使用类型的精度(float32而不是float)。其余部分保持不变(采用字符串和形状)。

工厂函数tables.Col.from_kind(kind, shape)可用于构造支持ndarrays的Col-Type。在我找到的任何地方都没有记录什么“种类”以及如何使用它;但是通过反复试验,我发现允许的“kind”是字符串的基本数据类型。即:'float''uint',... 没有精确度(非'float64'

因为我从h5py读取数据集(dset.dtype)得到numpy.dtypes,所以必须将它们转换为str并且需要删除精度。 最后,相关的行看起来像这样:

# get key, dtype and shapes of elements per dataset from the datasource files
val_keys, dtypes, element_shapes = _get_dtypes(datasources, element_axis=element_axis)

# for storing arrays in columns apparently one has to use "kind"
# "kind" cannot be created with dtype but only a string representing 
# the dtype w/o precision, e.g. 'float' or 'uint' 
dtypes_kind = [''.join(i for i in str(dtype) if not i.isdigit()) for dtype in dtypes]

# create table description as dictionary
description = {val_keys[i]: tables.Col.from_kind(dtypes_kind[i], shape=element_shapes[i]) for i in range(len(val_keys))}

然后将数据写入表中最终按照建议工作:

sample = table.row
sample[key] = my_array

由于这一切都感觉有点“hacky”并且记录不好,我仍然想知道,这是否不是PyTables的预期用途,并且会将这个问题留给abit看看s.o.了解更多...

答案 1 :(得分:0)

我知道现在有点晚了,但是我认为您问题的答案在于Float32Col的shape参数。

在文档中的用法如下:

<div class="sidebarnav"> <input id="navbar-button" type="checkbox"> <label for="navbar-button" id="navbar-label">Navbar button</label> <div class="content-1">Content 1</div> <div class="content-2"> Content 2</div> </div>

这是指向我所指的文档部分的链接 https://www.pytables.org/usersguide/tutorials.html