如果满足条件则替换 Numpy 元素
- 2025-02-27 09:05:00
- admin 原创
- 75
问题描述:
我有一个大型 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
是否有一个 numpy 函数可以加快这个速度?
解决方案 1:
>>> 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)
解决方案 2:
>>> 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]])
>>>
例如,参见使用布尔数组进行索引。
解决方案 3:
最快(也是最灵活)的方法是使用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]]
解决方案 4:
您可以像这样一步一步创建掩码阵列
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)
>>>
解决方案 5:
我是 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,'
')
# 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”)并相应地设置值。
解决方案 6:
我不确定我是否理解了你的问题,但如果你写:
mask_data[:3, :3] = 1
mask_data[3:, 3:] = 0
这将使 x 和 y 索引小于 3 的所有掩码数据值等于 1,其余值等于 0
相关推荐
热门文章
项目管理软件有哪些?
热门标签
曾咪二维码
扫码咨询,免费领取项目管理大礼包!
云禅道AD