我正在分析一些图像数据,这些数据由像素强度的大型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相对较新,因此,如果您有关于在大型数组中组织数据集的任何技巧,我希望能听到它们。
最佳答案
无论值多少钱,我经常对以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
完美配合。)关于python - PyTables:索引大型数组的多个维度,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11067916/