Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何将列动态分配给PyTables IsDescription类?_Python_Pytables - Fatal编程技术网

Python 如何将列动态分配给PyTables IsDescription类?

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

假设我有一个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.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使用数组的数据类型。这是我创建表的首选方法。