2012-05-21 42 views
6

我想检查一个NumPyArray的值是否在一个集合中,如果是这样,将该区域设置为一个数组= 1。如果没有设置keepRaster = 2检查一个集合中的值是否在python的numpy数组中

numpyArray = #some imported array 
repeatSet= ([3, 5, 6, 8]) 

confusedRaster = numpyArray[numpy.where(numpyArray in repeatSet)]= 1 

产量:

<type 'exceptions.TypeError'>: unhashable type: 'numpy.ndarray' 

有没有办法通过它循环?

for numpyArray 
     if numpyArray in repeatSet 
      confusedRaster = 1 
     else 
      keepRaster = 2 

为了澄清,并要求远一点的帮助:

我所想要知道的,和我目前做的,是把一个光栅输入到一个数组。我需要读取二维数组中的值,并根据这些值创建另一个数组。如果数组值在一个集合中,那么该值将为1.如果它不在集合中,则该值将从另一个输入派生,但现在我要说77。这是我目前使用的。我的测试输入有大约1500行和3500列。它总是在冻结行左右350

for rowd in range(0, width): 
    for cold in range (0, height): 
     if numpyarray.item(rowd,cold) in repeatSet: 
      confusedArray[rowd][cold] = 1 
     else: 
      if numpyarray.item(rowd,cold) == 0: 
       confusedArray[rowd][cold] = 0 
      else: 
       confusedArray[rowd][cold] = 2 

回答

12

在1.4及更高版本,numpy的提供in1d功能。

>>> test = np.array([0, 1, 2, 5, 0]) 
>>> states = [0, 2] 
>>> np.in1d(test, states) 
array([ True, False, True, False, True], dtype=bool) 

您可以使用作为分配的面具。

>>> test[np.in1d(test, states)] = 1 
>>> test 
array([1, 1, 1, 5, 1]) 

下面是numpy的索引和分配语法的一些更复杂的用法,我认为它会应用于您的问题。注意使用位运算符来替代if基于逻辑:

>>> numpy_array = numpy.arange(9).reshape((3, 3)) 
>>> confused_array = numpy.arange(9).reshape((3, 3)) % 2 
>>> mask = numpy.in1d(numpy_array, repeat_set).reshape(numpy_array.shape) 
>>> mask 
array([[False, False, False], 
     [ True, False, True], 
     [ True, False, True]], dtype=bool) 
>>> ~mask 
array([[ True, True, True], 
     [False, True, False], 
     [False, True, False]], dtype=bool) 
>>> numpy_array == 0 
array([[ True, False, False], 
     [False, False, False], 
     [False, False, False]], dtype=bool) 
>>> numpy_array != 0 
array([[False, True, True], 
     [ True, True, True], 
     [ True, True, True]], dtype=bool) 
>>> confused_array[mask] = 1 
>>> confused_array[~mask & (numpy_array == 0)] = 0 
>>> confused_array[~mask & (numpy_array != 0)] = 2 
>>> confused_array 
array([[0, 2, 2], 
     [1, 2, 1], 
     [1, 2, 1]]) 

另一种方法将是使用numpy.where,它创建一个全新的阵列,使用来自其中mask是真实的第二个参数的值,以及值从第三个参数mask是错误的。 (与分配,参数可以是标量或相同形状的阵列作为mask)。这可能比上述更多的有效的,它肯定更简洁:

>>> numpy.where(mask, 1, numpy.where(numpy_array == 0, 0, 2)) 
array([[0, 2, 2], 
     [1, 2, 1], 
     [1, 2, 1]]) 
+0

嗯,所以我明白。如果测试值位于状态列表中而不是True,那么它将等于1,否则它将等于它的值。 有没有办法使输出 数组([1,0,1,0,0]) – mkmitchell

+0

@mkmitchell,是的,你明白了。这与使用普通Python列表进行切片分配有点类似,但a)使用numpy更复杂的索引系统,并且b)遵循numpy约定,即将标量分配给数组的切片,将切片中的所有值分配给该标量值。 – senderle

+0

如果它是一个二维阵列呢? – mkmitchell

1

这里是做你whant什么的一种可能的方式:

numpyArray = np.array([1, 8, 35, 343, 23, 3, 8]) # could be n-Dimensional array 
repeatSet = np.array([3, 5, 6, 8]) 
mask = (numpyArray[...,None] == repeatSet[None,...]).any(axis=-1) 
print mask 
>>> [False True False False False True True] 
相关问题