替换引用列表中的数组值

时间:2015-04-08 13:06:33

标签: python numpy

我想要替换'数据'的值。数组使用' ref'列表:

import numpy as np

data = np.array([[1, 1 , 0 , 0 , 0 , 0 , 1 , 0],
                 [1, 1 , 1 , 1 , 9 , 1 , 1 , 0],
                 [1, 1 , 1 , 1 , 1 , 1 , 1 , 0],
                 [0, 0 , 1 , 1 , 1 , 1 , 1 , 0],
                 [0, 0 , 1 , 1 , 1 , 1 , 1 , 1],
                 [1, 1 , 1 , 1 , 1 , 1 , 1 , 0],
                 [1, 1 , 0 , 0 , 0 , 0 , 0 , 0],
                 [1, 1 , 0 , 0 , 0 , 0 , 1 , 0],
                 [1, 1 , 1 , 15 , 1 , 1 , 1 , 0],
                 [1, 1 , 1 , 1 , 1 , 1 , 1 , 0],
                 [0, 0 , 1 , 1 , 1 , 1 , 1 , 0],
                 [0, 0 , 1 , 1 , 12 , 1 , 1 , 1],
                 [1, 1 , 1 , 1 , 1 , 1 , 1 , 0],
                 [1, 1 , 0 , 0 , 0 , 0 , 0 , 0]])

ref = [9,12]

我试过:

data[data==ref] = 0

print data

但没有变化。

预期的数组应该将其中的9和12值替换为0。 如何做到这一点最快?

4 个答案:

答案 0 :(得分:5)

迭代一个numpy数组非常慢,比迭代Python列表要慢一些。

使用以下构造,您可以使用numpy.in1d()方法(http://docs.scipy.org/doc/numpy/reference/generated/numpy.in1d.html)将其全部保存在numpy中

以下内容将ref中的所有元素设置为-1,并将其简单地更改为将其设置为0

data[np.in1d(data, ref).reshape(data.shape)] = -1

答案 1 :(得分:1)

您可以遍历这些值并使用np.where来屏蔽数组以设置值:

In [67]:

ref = [9,12]
for e in ref:
    data[data == e] = 0
data
Out[67]:
array([[ 1,  1,  0,  0,  0,  0,  1,  0],
       [ 1,  1,  1,  1,  0,  1,  1,  0],
       [ 1,  1,  1,  1,  1,  1,  1,  0],
       [ 0,  0,  1,  1,  1,  1,  1,  0],
       [ 0,  0,  1,  1,  1,  1,  1,  1],
       [ 1,  1,  1,  1,  1,  1,  1,  0],
       [ 1,  1,  0,  0,  0,  0,  0,  0],
       [ 1,  1,  0,  0,  0,  0,  1,  0],
       [ 1,  1,  1, 15,  1,  1,  1,  0],
       [ 1,  1,  1,  1,  1,  1,  1,  0],
       [ 0,  0,  1,  1,  1,  1,  1,  0],
       [ 0,  0,  1,  1,  0,  1,  1,  1],
       [ 1,  1,  1,  1,  1,  1,  1,  0],
       [ 1,  1,  0,  0,  0,  0,  0,  0]])

失败的原因:

data[data==ref] = 0

您是在将数组与列表进行比较,这将导致标量布尔值为False这就是为什么它什么都不做。

只是为了表明@haave的回答是有效的,而且我的选择更好:

In [73]:

data[np.in1d(data, ref).reshape(data.shape)] = 0
data
Out[73]:
array([[ 1,  1,  0,  0,  0,  0,  1,  0],
       [ 1,  1,  1,  1,  0,  1,  1,  0],
       [ 1,  1,  1,  1,  1,  1,  1,  0],
       [ 0,  0,  1,  1,  1,  1,  1,  0],
       [ 0,  0,  1,  1,  1,  1,  1,  1],
       [ 1,  1,  1,  1,  1,  1,  1,  0],
       [ 1,  1,  0,  0,  0,  0,  0,  0],
       [ 1,  1,  0,  0,  0,  0,  1,  0],
       [ 1,  1,  1, 15,  1,  1,  1,  0],
       [ 1,  1,  1,  1,  1,  1,  1,  0],
       [ 0,  0,  1,  1,  1,  1,  1,  0],
       [ 0,  0,  1,  1,  0,  1,  1,  1],
       [ 1,  1,  1,  1,  1,  1,  1,  0],
       [ 1,  1,  0,  0,  0,  0,  0,  0]])

答案 2 :(得分:0)

另一种方法:

data[np.logical_or(*(data == e for e in ref))] = 0

答案 3 :(得分:0)

您可以使用broadcasting来获得所需的输出 -

data[np.any(data == np.asarray(ref)[:,None][:,None],0)] = 0

基本上,我们将ref转换为numpy arraynp.asarray为我们提供了一个向量。然后,将所有元素发送到第三维,并对2D数组equality-check执行data,作为data和{{之间匹配的布尔数组给出1}}在3D数组中。最后,我们执行ref以查找第三维的任何匹配,为我们提供2D掩码,我们可以使用它来索引np.any并将匹配的匹配设置为data