Python 基于多个条件的numpy数组设置值
我试图将numpy数组中的值设置为零,如果它相当于列表中的任何数字Python 基于多个条件的numpy数组设置值,python,arrays,numpy,Python,Arrays,Numpy,我试图将numpy数组中的值设置为零,如果它相当于列表中的任何数字 让我们考虑下面的数组 a = numpy.array([[1, 2, 3], [4, 8, 6], [7, 8, 9]]) 我想将列表[1,2,8]中的a的多个元素设置为0 结果应该是 [[0, 0, 3], [4, 0, 6], [7, 0, 9]] 对于单个元素,它很简单 a[a == 1] = 0 以上仅适用于单个整数。它如何用于列表?您可以使用numpy.vectorize创建自己的
让我们考虑下面的数组
a = numpy.array([[1, 2, 3], [4, 8, 6], [7, 8, 9]])
我想将列表[1,2,8]
中的a
的多个元素设置为0
结果应该是
[[0, 0, 3],
[4, 0, 6],
[7, 0, 9]]
对于单个元素,它很简单
a[a == 1] = 0
以上仅适用于单个整数。它如何用于列表?您可以使用
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。矢量化允许您使用更复杂的逻辑,同时具有简洁的优点。如果你喜欢代码高尔夫,你可以这样做:
a[np.vectorize(lambda x: (x in set([1,2,8])))(a)] = 0
您可以使用:
使用np.inad
可以执行以下操作:
>>> 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]])
结合我对关于np.where
的原始问题的评论,以及@Jaime在上文中使用np.inad
的出色回答:
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
哇,你以10秒的优势击败了我@qwwqwwq-它实际上看起来像13。;)我觉得使用numpy.where
应该可以做到这一点。但是,直观地选择numpy.where(a in[1,2,8],0,a)
给出了ValueError:具有多个元素的数组的真值是不明确的。使用a.any()或a.all()
。也许一个更专业的用户可以让它工作。顺便说一句,您可能已经意识到了这一点,但是如果您只有2-3个值,您只需要将它们与|操作符组合(或将不起作用)。e、 g.a[(a==1)|(a==2)|(a==8)]=0
numpy中的一个常见问题是试图将布尔数组与和,或,而不是&
,
,
结合起来。如果传入数组,前一个运算符将引发错误,但后一个运算符将按元素操作。当然,这是一种针对多个值进行测试的糟糕方法。这绝对是计算效率最高的方法,np。矢量化本质上只是pythonfor
循环的语法糖
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