如果满足条件,则替换 Numpy 元素

我有一个大的数字数组,我需要操作,以便每个元素改变为1或0,如果条件得到满足(将用作像素掩码后)。数组中有大约800万个元素,我当前的方法对于还原管道来说花费的时间太长:

for (y,x), value in numpy.ndenumerate(mask_data):


if mask_data[y,x]<3: #Good Pixel
mask_data[y,x]=1
elif mask_data[y,x]>3: #Bad Pixel
mask_data[y,x]=0

有没有一个数字函数可以加速这个过程?

247401 次浏览
>>> a = np.random.randint(0, 5, size=(5, 4))
>>> a
array([[0, 3, 3, 2],
[4, 1, 1, 2],
[3, 4, 2, 4],
[2, 4, 3, 0],
[1, 2, 3, 4]])
>>>
>>> a[a > 3] = -101
>>> a
array([[   0,    3,    3,    2],
[-101,    1,    1,    2],
[   3, -101,    2, -101],
[   2, -101,    3,    0],
[   1,    2,    3, -101]])
>>>

看,例如 使用布尔数组进行索引

您可以像下面这样一步创建掩码数组

mask_data = input_mask_data < 3

这将创建一个布尔数组,然后可以将其用作像素掩码。注意,我们没有更改输入数组(如在您的代码中) ,而是创建了一个新的数组来保存掩码数据——我建议这样做。

>>> input_mask_data = np.random.randint(0, 5, (3, 4))
>>> input_mask_data
array([[1, 3, 4, 0],
[4, 1, 2, 2],
[1, 2, 3, 0]])
>>> mask_data = input_mask_data < 3
>>> mask_data
array([[ True, False, False,  True],
[False,  True,  True,  True],
[ True,  True, False,  True]], dtype=bool)
>>>
>>> import numpy as np
>>> a = np.random.randint(0, 5, size=(5, 4))
>>> a
array([[4, 2, 1, 1],
[3, 0, 1, 2],
[2, 0, 1, 1],
[4, 0, 2, 3],
[0, 0, 0, 2]])
>>> b = a < 3
>>> b
array([[False,  True,  True,  True],
[False,  True,  True,  True],
[ True,  True,  True,  True],
[False,  True,  True, False],
[ True,  True,  True,  True]], dtype=bool)
>>>
>>> c = b.astype(int)
>>> c
array([[0, 1, 1, 1],
[0, 1, 1, 1],
[1, 1, 1, 1],
[0, 1, 1, 0],
[1, 1, 1, 1]])

你可以用以下方式缩短:

>>> c = (a < 3).astype(int)

我不确定我是否理解你的问题,但如果你写:

mask_data[:3, :3] = 1
mask_data[3:, 3:] = 0

这将使 x 和 y 索引小于3的掩码数据的所有值等于1,而所有其余的值等于0

最快(也是最灵活)的方法使用 Np.where,它根据掩码(真值和假值的数组)在两个数组之间进行选择:

import numpy as np
a = np.random.randint(0, 5, size=(5, 4))
b = np.where(a<3,0,1)
print('a:',a)
print()
print('b:',b)

它将产生:

a: [[1 4 0 1]
[1 3 2 4]
[1 0 2 1]
[3 1 0 0]
[1 4 0 1]]


b: [[0 1 0 0]
[0 1 0 1]
[0 0 0 0]
[1 0 0 0]
[0 1 0 0]]

我是一个使用 Numpy 的菜鸟,上面的答案并没有直接修改我的数组,所以我把我想到的发布出来:

import numpy as np


arr = np.array([[[10,20,30,255],[40,50,60,255]],
[[70,80,90,255],[100,110,120,255]],
[[170,180,190,255],[230,240,250,255]]])


# Change 1:
# Set every value to 0 if first element is smaller than 80
arr[arr[:,:,0] < 80] = 0


print('Change 1:',arr,'\n')


# Change 2:
# Set every value to 1 if bigger than 180 and smaller than 240
# OR if equal to 170
arr[(arr > 180) & (arr < 240) | (arr == 170)] = 1


print('Change 2:',arr)

这就产生了:

Change 1: [[[  0   0   0   0]
[  0   0   0   0]]


[[  0   0   0   0]
[100 110 120 255]]


[[170 180 190 255]
[230 240 250 255]]]


Change 2: [[[  0   0   0   0]
[  0   0   0   0]]


[[  0   0   0   0]
[100 110 120 255]]


[[  1 180   1 255]
[  1 240 250 255]]]

通过这种方式,您可以添加成吨的条件,如“更改2”,并相应地设置值。