在PyTables单元中存储任意形状的多维数组可能吗?

1 投票
2 回答
2025 浏览
提问于 2025-04-17 10:35

PyTables可以让我们从用户自己定义的类创建表格,这些类需要继承自IsDescription类。这样做的好处是,它支持多维单元格,就像下面文档中的例子一样:

class Particle(IsDescription):
    name = StringCol(itemsize=16) # 16-character string
    lati = Int32Col() # integer
    longi = Int32Col() # integer
    pressure = Float32Col(shape=(2,3)) # array of floats (single-precision) 
    temperature = Float64Col(shape=(2,3)) # array of doubles (double-precision)

不过,能不能在一个单元格里存放形状不规则的多维数组呢?就像上面的例子,我们可以写成pressure = Float32Col(shape=(x, y)),其中xy是在插入每一行时确定的。

如果不行,那有什么更好的方法呢?是不是可以把每个(形状不规则的)多维数组存放在一个CArray里,并给它一个独特的名字,然后把这些名字放在一个主索引表里?我想的应用场景是存储图像和相关的元数据,我希望能够查询这些数据,并且可以使用numexpr进行处理。

如果有关于PyTables的最佳实践的建议,我会非常感激!

2 个回答

0

简单来说,答案是“不”,我认为这是hdf5的一个“限制”,而不是pytables的问题。

原因在于,每个存储单元(复合数据集)必须有一个明确的大小。如果其中一个或多个部分的大小可以变化,那它显然就无法保持固定。需要注意的是,在hdf5中确实可以调整和扩展数据集(pytables对此使用得很频繁),但不能改变数组内部数据单元的大小。

我觉得最好的办法是: a) 设定一个明确的大小,并提供一个标志来处理溢出的情况。如果最大的合理大小仍然比较小,并且你能接受丢弃一些尾部数据,这样做效果很好。需要注意的是,你可能可以通过hdf5的压缩功能来减少未使用的磁盘空间。 b) 按照你的建议,在同一个文件中创建一个新的CArray,只有在需要时才读取它。(为了保持整洁,你可能想把这些都放在自己的组里)

实际上,HDF5有一个API,专门用于在hdf5文件中存储图像,并且经过优化。我认为在pytables中并没有提供这个功能。

1

长话短说就是“可以,但你可能不想这样做。”

PyTables 可能不直接支持这个功能,但 HDF5 是支持创建嵌套的可变长度数据类型的,这样可以在多个维度中使用不规则数组。如果你想尝试这个方法,可以使用 h5py,并查看 HDF5 用户指南,数据类型章节。具体可以看第 6.4.3.2.3 节:可变长度数据类型。(我本来想给你链接,但他们似乎没有做这么深的链接)。

就我个人而言,我会把你的数据整理成数据集的组,而不是放在一个单一的表格里。也就是说,像这样:

/particles/particlename1/pressure
/particles/particlename1/temperature
/particles/particlename2/pressure
/particles/particlename2/temperature

等等。纬度和经度的值应该作为 /particles/particlename 组的属性,而不是作为数据集,不过把它们放在小的数据集中也是完全可以的。

如果你想根据纬度和经度进行搜索,那么有一个包含纬度/经度/名称列的数据集会比较好。如果你想更高级一点,HDF5 还有一种数据类型可以用来存储引用,这样你就可以存储指向一个数据集,甚至是数据集的一个子集的指针。

撰写回答