PyTables:索引大型数组的多个维度
Posted
技术标签:
【中文标题】PyTables:索引大型数组的多个维度【英文标题】:PyTables: indexing multiple dimensions of large arrays 【发布时间】:2012-06-19 12:59:39 【问题描述】:我正在分析一些成像数据,这些数据由像素强度的大型 3 维数组组成,尺寸为 [frame, x, y]
。由于这些通常太大而无法保存在内存中,因此它们作为 PyTables 数组驻留在硬盘上。
我希望能够读取所有帧中任意像素子集的强度。这样做的自然方法似乎是列表索引:
import numpy as np
import tables
tmph5 = tables.open_file('temp.hdf5', 'w')
bigarray = tmph5.create_array('/', 'bigarray', np.random.randn(1000, 200, 100))
roipixels = [[0, 1, 2, 4, 6], [34, 35, 36, 40, 41]]
roidata = bigarray[:, roipixels[0], roipixels[1]]
# IndexError: Only one selection list is allowed
不幸的是,PyTables 目前似乎只支持一组列表索引。另一个问题是列表索引不能包含重复项——我无法同时读取像素[1, 2]
和[1, 3]
,因为我的像素x 坐标列表将包含[1, 1]
。我知道我可以遍历数组中的行:
roidata = np.asarray([row[roipixels[0], roipixels[1]] for row in bigarray])
但是对于我正在处理的大量帧,这些迭代读取变得非常慢。
有更好的方法吗?我对 PyTables 比较陌生,所以如果您有任何关于在大型数组中组织数据集的技巧,我很想听听。
【问题讨论】:
我认为这实际上是 hdf5 的潜在限制,而不是 pytables 限制(我可能完全错了......)。无论如何,我发现h5py
对于非表格数据来说更自然。但是,在这种情况下,它具有相同的限制。
【参考方案1】:
不管它值多少钱,我经常对以 hdf 格式存储的 3D 地震数据做同样的事情。
由于嵌套循环,迭代读取速度很慢。如果您只执行一个循环(而不是遍历每一行),它会非常快(至少在使用h5py
时。我通常只使用pytables
存储类似表的数据)并且完全按照您的意愿进行操作。
在大多数情况下,您需要遍历索引列表,而不是遍历每一行。
基本上,你想要:
roidata = np.vstack([bigarray[:,i,j] for i,j in zip(*roipixels)])
代替:
roidata = np.asarray([row[roipixels[0],roipixels[1]] for row in bigarray])
如果这是您最常见的用例,调整存储数组的块大小将有很大帮助。在您的情况下,您需要长而窄的块,沿第一个轴的长度最长。
(警告:我没有用 pytables
测试过这个,但它和 h5py
完美匹配。)
【讨论】:
谢谢,乔。我想这可以回答我的问题,但我惊讶地发现你建议的行在我的情况下实际上读起来要慢得多(大约 15 倍)。我不确定这是否是 Pytables 与 h5py 的问题,或者它是否与我正在使用的块形状或压缩有关。我会检查 h5py 看看它是否表现更好。 它可能由存储数组的块大小控制。如果底层 hdf 文件针对按行访问进行了优化,那么基于行的访问会更快。我不知道 pytables 如何计算要使用的块大小。无论如何,祝你好运!以上是关于PyTables:索引大型数组的多个维度的主要内容,如果未能解决你的问题,请参考以下文章