Python 如何将列动态分配给PyTables IsDescription类?
假设我有一个PyTables描述类:Python 如何将列动态分配给PyTables IsDescription类?,python,pytables,Python,Pytables,假设我有一个PyTables描述类: In [1]: import tables as tb class DataDescr(tb.IsDescription): timestamp = tb.Time64Col(pos=0) value_b = tb.Float32Col(pos=2) 现在我动态地分配值a。我需要这样做,因为这个列的形状取决于一些用户输入 In [2]: DataDescr.value_a = tb.Float
In [1]: import tables as tb
class DataDescr(tb.IsDescription):
timestamp = tb.Time64Col(pos=0)
value_b = tb.Float32Col(pos=2)
现在我动态地分配值a
。我需要这样做,因为这个列的形状取决于一些用户输入
In [2]: DataDescr.value_a = tb.Float32Col(pos=1, shape=given_shape)
但是,当查看使用此描述创建的表时,我看不到新列
In [3]: h5file = tb.open_file('goodstuff.h5', mode='w')
table = h5file.create_table('/', 'data', DataDescr)
table
Out[3]: /data (Table(0,)) ''
description := {
"timestamp": Time64Col(shape=(), dflt=0.0, pos=0),
"value_b": Float32Col(shape=(), dflt=0.0, pos=1)}
byteorder := 'little'
chunkshape := (5461,)
如何解决此问题?有几个选项可供选择(请参阅) 选项1:添加带有
IsDescription.columns
IsDescription
对象具有一个columns
属性,该属性在字典中存储列信息,可用于动态赋值。如问题所述,从一节基本完整的课开始
class DataDescr(tb.IsDescription):
timestamp = tb.Time64Col(pos=0)
value_b = tb.Float32Col(pos=2)
…然后添加缺少的属性
DataDescr.columns['value_a'] = tb.Float32Col(pos=1, shape=(3, 2))
选项2:使用字典描述 与其说是类描述,不如从字典描述开始
data_descr = dict(
timestamp=tb.Float64Col(pos=1),
value_b=tb.Float32Col(pos=2),
)
…然后在字典中添加一个条目
data_descr['value_a'] = tb.Float32Col(pos=1, shape=(3, 2))
选项3:一次性创建NumPy数据类型描述 由于NumPy数据类型不支持项分配,因此此方法要求一次创建所有描述。如果这是一个问题,选项1和2可用
data_descr = np.dtype([
('timestamp', np.float64),
('value_a', (np.float32, (3, 2))),
('value_b', np.float32),
])
[可能很危险]选项4:修改dict条目的形状 我将提到最后一个选项,它不一定得到支持。因此,最好远离这个选项 从没有指定大小的完整词典开始后
data_descr = dict(
timestamp=tb.Float64Col(pos=1),
value_a=tb.Float32Col(pos=1),
value_b=tb.Float32Col(pos=2),
)
…修改'value\u a'
条目的形状
data_descr['value_a'].shape = (3, 2)
注意:这不适用于类描述,原因我不知道。
class DataDescr(tb.IsDescription):
timestamp = tb.Time64Col(pos=0)
value_a = tb.Float32Col(pos=1)
value_b = tb.Float32Col(pos=2)
DataDescr.columns['value_a'].shape = (3, 2)
h5file = tb.open_file('goodstuff.h5', mode='w')
table = h5file.create_table('/', 'data', DataDescr)
row = table.row
row['value_a'] = np.ones((3, 2)) * 5
row.append()
结果:
TypeError: invalid type (<class 'numpy.ndarray'>) for column ``value_a``
TypeError:列``value\u a的类型()无效``
或者,您可以通过编程创建Numpy数据类型来定义表描述,而不是使用tb.IsDescription
。所有3列的数据类型如下:tb_dt=np.dtype([('timestamp',np.float64),('value_a',(np.float32,(3,2)),('value_b',np.float32)]
。然后,在创建表时参考tb_dt
。列的顺序将与数据类型相同。谢谢@kcw78,这可能是一个更好的解决方案。我会把它添加到我的答案中。看起来还可以使用字典:是的,有5种方法来定义表。这些选项在Pytables文档中为文件定义。create_table()
(请参见description
参数)。我倾向于使用Numpy数据类型b/c,在HDF5和Numpy阵列之间交换大量数据。事实上,如果将表数据加载到Numpy结构化数组中,可以使用description=
或obj=
参数引用它,并定义表,同时加载数据。:-)Pytables使用数组的数据类型。这是我创建表的首选方法。