Python 三维numpy阵列中ROI的快速提取方法

Python 三维numpy阵列中ROI的快速提取方法,python,arrays,numpy,indexing,Python,Arrays,Numpy,Indexing,我有一个1D阵列,其中包含一些视频数据: data=np.random.randint(0,high=255,size=(500*500*100),dtype=np.uint8) imgs=np.reshape(data,(100, 500,500)) # 100 frames, 500x500 pixels 我想沿着所有帧提取特定的感兴趣区域 idx=np.random.randint(0,high=500*500,size=(49, 300)) #300 rois, 49 points e

我有一个1D阵列,其中包含一些视频数据:

data=np.random.randint(0,high=255,size=(500*500*100),dtype=np.uint8)
imgs=np.reshape(data,(100, 500,500)) # 100 frames, 500x500 pixels
我想沿着所有帧提取特定的感兴趣区域

idx=np.random.randint(0,high=500*500,size=(49, 300)) #300 rois, 49 points each
rois=imgs.reshape(100, -1)[:,idx]
我将每个帧展平,然后沿第一维提取ROI。真正的imgs数组比这里显示的要大,并且前面的索引操作可能有点慢。如果我在下面以不同的方式重塑IMG,rois.size是相同的,索引速度更快,但这检索到错误的数据

%timeit imgs.reshape(100, -1)[:,idx] # 13 ms
%timeit imgs.reshape(-1, 100)[idx, :] # 1.2 ms, much faster but wrong data

在我的真实代码中,差异几乎是50倍。有什么方法可以快速索引IMG吗?

通过对ROI像素进行排序并使用转置坐标,似乎至少可以节省一点时间:

>>> def f_pp(im2D, idx):
...     s = np.argsort(idx.ravel())
...     out = np.empty((*idx.shape, im2D.shape[0]), im2D.dtype)
...     out.reshape(-1, im2D.shape[0])[s] = im2D.T[idx.ravel()[s]]
...     return out
... 

# results are the same:
>>> np.all(f_pp(imgs.reshape(100, -1), idx) == np.moveaxis(imgs.reshape(100, -1)[:, idx], 0, 2))
True

>>> timeit("imgs.reshape(100, -1)[:, idx]", globals=globals(), number=100)
1.3392871069954708
# transposing alone is not enough:
>>> timeit("imgs.reshape(100, -1).T[idx]", globals=globals(), number=100)
1.3336799899989273
# but together with sorting I see a 2x speedup
>>> timeit("f_pp(imgs.reshape(100, -1), idx)", globals=globals(), number=100)
0.5874412529956317
# still much worse than if we had a more favorable memory layout in
# the first place
>>> timeit("imgs.reshape(-1, 100)[idx]", globals=globals(), number=100)
0.06296327701420523