2017-03-01 68 views
2

我是NumPy的新手,并且遇到了在numpy数组上运行一些条件语句的问题。比方说,我有一个看起来像这样3个numpy的数组:对numpy数组的条件操作

一个:

​​

B:

[[6, 9, 8, 6], 
[7, 7, 9, 6], 
[8, 6, 5, 7]] 

和c:

[[0, 0, 0, 0], 
[0, 0, 0, 0], 
[0, 0, 0, 0]] 

我有一个条件语句对于a和b,我希望使用b的值(如果符合a和b的条件)来计算c的值:

c[(a > 3) & (b > 8)]+=b*2 

我得到一个错误说:

Traceback (most recent call last): 
    File "<interactive input>", line 1, in <module> 
ValueError: non-broadcastable output operand with shape (1,) doesn't match the broadcast shape (3,4) 

任何想法如何,我可以做到这一点?

我想C的输出如下所示:

[[0, 18, 0, 0], 
[0, 0, 0, 0], 
[0, 0, 0, 0]] 
+0

谢谢!在每个人工作的同时赞扬每个人。我接受了来自@Psidom的np.where的答案,因为它对我来说最有意义并且运行速度最快(我的实际脚本将运行这些条件几百万次) – bobby12345

回答

7

您可以使用numpy.where

np.where((a > 3) & (b > 8), c + b*2, c) 
#array([[ 0, 18, 0, 0], 
#  [ 0, 0, 0, 0], 
#  [ 0, 0, 0, 0]]) 

或者算术:

c + b*2 * ((a > 3) & (b > 8)) 
#array([[ 0, 18, 0, 0], 
#  [ 0, 0, 0, 0], 
#  [ 0, 0, 0, 0]]) 
6

的问题是,你屏蔽接收部分,但不能掩盖发件人部分。因此:

c[(a > 3) & (b > 8)]+=b*2 
#^1x1 matrix  ^3x4 matrix 

尺寸不一样。由于要执行元素方面除了(根据你的例子),你可以简单地将切片添加到右侧的部分,以及:

c[(a > 3) & (b > 8)]+=b[(a > 3) & (b > 8)]*2

或使其更高效:

mask = (a > 3) & (b > 8) 
c[mask] = b[mask]*2
1

在numpy的表达会得到理想的效果略有变化:

c += ((a > 3) & (b > 8)) * b*2 

在这里首先创建包含布尔值的掩码矩阵,从((a > 3) & (b > 8)),然后乘以矩阵b*2这又产生3x4矩阵,可以很容易地添加到c