Python 如果满足条件,则更换Numpy元件
我有一个大的numpy数组,需要对其进行操作,以便在满足条件时将每个元素更改为1或0(稍后将用作像素掩码)。阵列中大约有800万个元素,我当前的方法对于缩减管道来说花费的时间太长:Python 如果满足条件,则更换Numpy元件,python,arrays,numpy,conditional,Python,Arrays,Numpy,Conditional,我有一个大的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
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
对于(y,x),数值单位为numpy.ndenumerate(掩码数据):
如果遮罩_数据[y,x]3:#坏像素
掩码_数据[y,x]=0
有没有一个numpy函数可以加速这个过程
>>> 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
mask_data=输入_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)
>>>
输入掩码数据=np.random.randint(0,5,3,4))
>>>输入屏蔽数据
数组([[1,3,4,0],
[4, 1, 2, 2],
[1, 2, 3, 0]])
>>>掩码数据=输入掩码数据<3
>>>屏蔽数据
数组([[True,False,False,True],
[假,真,真,真],
[True,True,False,True]],dtype=bool)
>>>
>>将numpy作为np导入
>>>a=np.random.randint(0,5,size=(5,4))
>>>a
数组([[4,2,1,1],
[3, 0, 1, 2],
[2, 0, 1, 1],
[4, 0, 2, 3],
[0, 0, 0, 2]])
>>>b=a<3
>>>b
数组([[False,True,True,True],
[假,真,真,真],
[真的,真的,真的,真的],
[假,真,真,假],
[True,True,True,True]],dtype=bool)
>>>
>>>c=b.aType(int)
>>>c
数组([[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)
>c=(a<3).astype(int)
我不确定我是否理解了你的问题,但如果你写:
mask_data[:3, :3] = 1
mask_data[3:, 3:] = 0
这将使x和y索引小于3的掩码数据的所有值都等于1,其余所有值都等于0。使用最快(也是最灵活)的方法是,根据掩码(真值和假值数组)在两个数组之间进行选择:
如果
mask_data[y,x]==3
,您希望发生什么?好的一点,那仍然是一个坏像素。如果mask_data[y,x]>=3:是,我将把条件更改为。如果OP真的想要0和1,他可以使用.astype(int)
或*1
,但是True
和False
的数组也一样好。非常好的东西,谢谢!如果要引用更改的值,可以使用类似a[a>3]=-101+a[a>3]
@pexmar的方法,但如果使用a[a>3]=-101+a[a>3]
而不是a[a>3]+=-101
您很可能会面临内存泄漏。您如何引用pexmar询问时更改的值?如何在特定列中实现这一点,而不必切掉一些列,然后重新分配回来?例如,当条件满足时,只有列[2,3]中的元素应更改值,而其他列无论是否满足条件都不会更改。True,但仅适用于0和1的情况。请参阅下面更一般的答案(以效率为代价)。如果不满足条件,我不想替换为任何内容,那么最好的方法是什么?即,仅在满足条件时替换为提供的值,如果不保留原始数字……要替换a中小于3的所有值,并保持其余值不变,请使用a[a]
mask_data[:3, :3] = 1
mask_data[3:, 3:] = 0
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]]