我有一个(更大的(矩阵,看起来像这样:
0 0 4 0 0 1
1 0 0 0 1 0
2 1 0 1 0 0
0 0 0 0 0 0
-1 0 -2 -3 0 0
0 0 -1 -2 0 -2
0 -5 0 -1 0 -1
那必须变成这样的东西:
0 1 1 1 0 1
0 0 1 0 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
0 1 0 0 1 1
1 1 0 0 1 0
因此,第一个垫子中的每个单元格存储必须擦除多少个相邻像素(以按列的方式(像素(生成的像素是用于此目的的布尔掩码(。 如果第一个矩阵中的值为正,则必须向上擦除像素,在负情况下,向下擦除像素。
我已经用双精度 for 实现了这一点,结果证明它非常慢......
那么,有一种方法可以使用numpy全局方法做到这一点吗?
(我使用的是python 3.8,但我实际上可以使用任何版本(
编辑:
我使用的双 for 循环: 其中"pixels_to_erase"是第一个垫子,"mask_array"是第二个垫
子for i in range(nRows):
for j in range(nCols):
signal = np.sign(pixels_to_erase[i,j])
if signal > 0:
upper_bound = i - pixels_to_erase
if upper_bound < 0:
upper_bound = 0
lower_bound = i
else:
upper_bound = i
lower_bound = i + pixels_to_erase
if lower_bound > max_row:
lower_bound = max_row
mask_array[upper_bound:lower_bound,j] = 0
(实际上,这是一个更大的代码的改编部分,如果需要,我可以将其发布在要点中(
如果每个位置的数字相对较小,则对不同值的循环可能会给您带来更好的性能:
import numpy as np
m = np.array([
[0, 0, 4, 0, 0, 1],
[1, 0, 0, 0, 1, 0],
[2, 1, 0, 1, 0, 0],
[0, 0, 0, 0, 0, 0],
[-1, 0, -2, -3, 0, 0],
[0, 0, -1, -2, 0, -2],
[0, -5, 0 , -1, 0, -1] ])
result = np.ones(np.shape(m), dtype=int)
for d in np.unique(m):
if d == 0: continue
mask = m if d < 0 else m[::-1,:]
mask = np.cumsum(np.cumsum(mask==d,axis=0),axis=0)-1
mask = 1 - (mask>0)*(mask<=abs(d))
if d>0 : mask = mask[::-1,:]
result *= mask
#print(d)
#print(mask)
print(result)
这将单独处理每个擦除值,并为向上或向下的值生成一个遮罩。 结果是所有掩码的交集。
然而。。。 查看数字的模式,我怀疑擦除数字将始终围绕给定点按递增/递减顺序排列。 这将适用于一个更简单(和更快(的解决方案,您只需处理上一行和下一行即可确定是否需要清除点:
result = np.ones(np.shape(m), dtype=int)
result[1:,:] *= m[:-1,:]>=0
result[:-1,:] *= m[1:,:] <=0
print(result)