基于多个条件设置numpy数组的值

时间:2014-01-03 01:00:21

标签: python arrays numpy

我试图将numpy数组中的值设置为零,如果它等于列表中的任何数字。

让我们考虑以下数组

  a = numpy.array([[1, 2, 3], [4, 8, 6], [7, 8, 9]])

我想在a[1, 2, 8]列表中设置0的多个元素。

结果应为

   [[0, 0, 3],
    [4, 0, 6],
    [7, 0, 9]]

对于单个元素,它很简单

   a[a == 1] = 0

以上仅适用于单个整数。它如何适用于列表?

4 个答案:

答案 0 :(得分:5)

使用np.in1d,您可以执行以下操作:

>>> a = np.array([[1, 2, 3], [4, 8, 6], [7, 8, 9]])
>>> np.in1d(a, [1, 2, 8])
array([ True,  True, False, False,  True, False, False,  True, False], dtype=bool)
>>> a[np.in1d(a, [1, 2, 8]).reshape(a.shape)] = 0
>>> a
array([[0, 0, 3],
       [4, 0, 6],
       [7, 0, 9]])

答案 1 :(得分:2)

将我的评论与np.where的原始问题以及@Jaime上面使用np.in1d的优秀答案结合起来:

import numpy as np
a = np.array([[1, 2, 3], [4, 8, 6], [7, 8, 9]])
a = np.where(np.in1d(a, [1,2,8]).reshape(a.shape), 0, a)

修改 看起来Jaime的解决方案稍微快一些:

In [3]: %timeit a[np.in1d(a, [1, 2, 8]).reshape(a.shape)] = 0
10000 loops, best of 3: 45.8 µs per loop
In [4]: %timeit np.where(np.in1d(a, [1,2,8]).reshape(a.shape), 0, a)
10000 loops, best of 3: 66.7 µs per loop

答案 2 :(得分:1)

您可以使用numpy.vectorize创建自己的矢量化函数:

import numpy as np
a = np.array([[1, 2, 3], [4, 8, 6], [7, 8, 9]])

def is_target_number(x):
    if x in set([1,2,8]):
        return True
    else:
        return False

f = np.vectorize(is_target_number)

a[f(a)] = 0

默认情况下,很多类似等号运算符的运算符已经过向量化,numpy.vectorize允许您使用更复杂的逻辑,并具有相同的简洁性。如果你进入代码高尔夫,你可以做这样的事情:

a[np.vectorize(lambda x: (x in set([1,2,8])))(a)] = 0

答案 3 :(得分:1)

您可以使用numpy.vectorize

>>> import numpy
>>> a = numpy.array([[1, 2, 3], [4, 8, 6], [7, 8, 9]])
>>> lst = [1, 2, 8]
>>> a[numpy.vectorize(lambda x: x in lst)(a)] = 0
>>> a
array([[0, 0, 3],
       [4, 0, 6],
       [7, 0, 9]])
>>>