Val*_*ntz 5 python arrays numpy image-processing gil
假设我有一个numpy数组a,我想创建一个新的数组,b这
b[i, j]是一个函数,比如说:
a[i-1, j-1], a[i-1, j ], a[i-1, j+1],
a[i , j-1], a[i , j ], a[i , j+1],
a[i+1, j-1], a[i+1, j ], a[i+1, j+1]
Run Code Online (Sandbox Code Playgroud)
最快的方法是什么?
由于这是一个可分离的过滤器,有没有办法在多个线程中运行它?(不是进程,因为我必须将数据复制回来)
或者正在编写C代码以绕过GIL强制执行?
部分解决方案(如假设功能是线性的)也是受欢迎的.
使用此类滑动窗口的理想numpy方法是构造一个 4D 数组
C.shape = (N,M,3,3)
Run Code Online (Sandbox Code Playgroud)
在哪里
C[i,j,:,:] = np.array([a[i-1, j-1], a[i-1, j ], a[i-1, j+1],
a[i , j-1], a[i , j ], a[i , j+1],
a[i+1, j-1], a[i+1, j ], a[i+1, j+1]])
Run Code Online (Sandbox Code Playgroud)
并编写您的函数,对最后两个维度进行某种缩减。 sum或者mean是典型的,例如
B = C.sum(axis=(2,3))
Run Code Online (Sandbox Code Playgroud)
其他 SO 问题展示了如何使用np.lib.stride_tricks.as_strided来构造这样的数组。但如果只有 3x3 子数组,执行类似操作可能会同样快
C = np.zeros((N,M,3,3))
C[:,:,0,0] = a[:-1,:-1]
etc.
Run Code Online (Sandbox Code Playgroud)
(或使用hstackandvstack达到相同的效果)。
但是跨步方法的一个好处(或者可能不太好)是它不涉及复制任何数据a- 它只是一个视图。
至于将工作分成几部分,我可以想象使用切片C(在第一个二维上),例如
C[0:100,0:100,:,:].sum(axis=(2,3))
Run Code Online (Sandbox Code Playgroud)