2015-11-15 27 views
1

我在范围(0,180)中有一个数字的numpy数组。对于每个值,如果值x大于90,我想用180替换它 - x用于条件减去现有值的Numpy布尔索引掩码

例如5→5,50→50,100→80,175→5。

由于numpy的强大功能在于它能够一次对整个阵列进行操作,例如, A = A + 1中由1递增在所有项目,我试图用一个布尔掩模以下:

>>> import numpy as np 
>>> a = np.random.randint(180, size=(20)) 
>>> a 
array([150, 136, 28, 77, 7, 165, 114, 71, 150, 86, 129, 156, 33, 
     34, 91, 87, 105, 9, 5, 108]) 
>>> a[a > 90] = 180 - a 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: NumPy boolean array indexing assignment cannot assign 20 input values to the 10 output values where the mask is true 
>>> 

失败的原因没有在掩模阵列的长度和原始阵列的失配。 我该怎么做(无需手动迭代数组)?

回答

2

一种方法是使用np.where

>>> a 
array([172, 47, 58, 47, 162, 130, 16, 173, 125, 40, 25, 32, 123, 
     142, 89, 29, 120, 2, 97, 116]) 
>>> np.where(a>90, 180-a, a) 
array([ 8, 47, 58, 47, 18, 50, 16, 7, 55, 40, 25, 32, 57, 38, 89, 29, 60, 
     2, 83, 64]) 

注意它返回一个新的数组,而不是修改现有阵列。如果您愿意,您可以将其指定回a,但该更改不会被引用原始数组的其他任何变量“看到”。

你也可以做你做了什么,如果你选择的赋值两侧的相应要素:

>>> a[a>90] = 180 - a[a>90] 
>>> a 
array([ 8, 47, 58, 47, 18, 50, 16, 7, 55, 40, 25, 32, 57, 38, 89, 29, 60, 
     2, 83, 64]) 
+0

感谢。关于第一种方法和你提到的关于变化不被其他变量看到的变化,如果新的数组被分配回a;你是否仅仅是指,如果你已经在更新之前计算了它们?在这种情况下,我自然希望不得不重新计算它们,以便考虑到! – feedMe

+0

@feedMe:我的意思是,如果你做了'a = numpy.random.randint(...)'然后做'b = a',然后做'a = np.where(...)',这不会影响'b',而第二种方法('a [a> 90] = ...')会。这不是特定于numpy,但有时候对于不熟悉Python如何工作的人来说是一个难题。 – BrenBarn