替换引用列表中的数组值



我想用"ref"列表替换"data"数组的值:

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。最快的方法是什么?

在numpy数组中迭代非常慢,比在Python列表中迭代慢一个数量级。

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

下面将ref中的所有元素设置为-1,并简单地更改为将它们设置为0

data[np.in1d(data, ref).reshape(data.shape)] = -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]])

另一种方法:

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

您可以使用broadcasting来实现所需的输出-

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

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

最新更新