我有一个多维numpy数组,其中元素是真实的或错误的值:
import numpy as np
#just making a toy array grid to show what I want to do
grid = np.ones((4,4),dtype = 'bool')
grid[0,0]=False
grid[-1,-1]=False
#now grid has a few false values but is a 4x4 filled with mostly true values
现在我需要生成另一个数组m,其中每个站点的值m [i,j]取决于网格[i:i 2,j:j 2],如
中M = np.empty((4x4)) #elements to be filled
#here is the part I want to clean up
for ii in range(4):
for jj in range(4):
#details here are unimportant. It's just that M[ii,jj] depends on
#multiple elements of grid in some way
if ii+2<=4 and jj+2<=4:
M[ii,jj] = np.all(grid[ii:ii+2,jj:jj+2]==True)
else:
M[ii,jj] = False
是否有一些方法可以使用网格中的元素填充阵列M,而无需双重循环?
方法#1
这是2D
卷积的一种方法 -
from scipy.signal import convolve2d as conv2
out = (conv2(grid,np.ones((2,2),dtype=int),'valid')==4).astype(int)
样本运行 -
In [118]: grid
Out[118]:
array([[False, True, True, True],
[ True, True, True, True],
[ True, True, True, True],
[ True, True, True, False]], dtype=bool)
In [119]: (conv2(grid,np.ones((2,2),dtype=int),'valid')==4).astype(int)
Out[119]:
array([[0, 1, 1],
[1, 1, 1],
[1, 1, 0]])
请注意,预期输出的最后一行和最后一列将是所有初始化输出数组的零。这是因为代码的滑动性质,因为它不会沿行和列有很大的程度。
方法#2
这是2D
均匀过滤器 -
from scipy.ndimage.filters import uniform_filter as unif2d
out = unif2d(grid,size=2).astype(int)[1:,1:]
方法#3
这是4D
滑动窗户视图 -
from skimage.util import view_as_windows as viewW
out = viewW(grid,(2,2)).all(axis=(2,3)).astype(int)
使用该all(axis=(2,3))
,我们只是在每个窗口的两个维度上检查所有元素,以使所有元素均为True
元素。
运行时测试
In [122]: grid = np.random.rand(5000,5000)>0.1
In [123]: %timeit (conv2(grid,np.ones((2,2),dtype=int),'valid')==4).astype(int)
1 loops, best of 3: 520 ms per loop
In [124]: %timeit unif2d(grid,size=2).astype(int)[1:,1:]
1 loops, best of 3: 210 ms per loop
In [125]: %timeit viewW(grid,(2,2)).all(axis=(2,3)).astype(int)
1 loops, best of 3: 614 ms per loop