2014-10-08 1429 views
36

我试图在python中执行元素明智的分割,但是如果遇到零,我需要商数为零。NumPy:用0除零返回0

例如:

array1 = np.array([0, 1, 2]) 
array2 = np.array([0, 1, 1]) 

array1/array2 # should be np.array([0, 1, 2]) 

我总是可以只使用一个for循环,通过我的数据,但要真正利用numpy的的优化,我需要的分频功能,以零次失误后分返回0,而不是忽略的错误。

除非我错过了某些东西,否则numpy.seterr()可能会在错误时返回值。有没有人有任何其他的建议,我可以如何通过零错误处理设置我自己的鸿沟,从而获得最好的numpy?

+0

在我的Python版本(Python的2.7.11 |连续分析公司)这正是你得到的输出。有警告。 – 2016-08-09 16:15:25

+0

最简洁的正确答案是https://stackoverflow.com/a/37977222/2116338 – mrplants 2017-12-02 21:51:26

回答

40

在numpy的V1。7+,您可以利用ufuncs的“where”选项。你可以在一行中完成任务,而不必处理errstate上下文管理器。

>>> a = np.array([-1, 0, 1, 2, 3], dtype=float) 
>>> b = np.array([ 0, 0, 0, 2, 2], dtype=float) 

>>> c = np.divide(a, b, out=np.zeros_like(a), where=b!=0) 
>>> print(c) 
[ 0. 0. 0. 1. 1.5] 

在这种情况下,它在任何地方进行除法运算'where'b不等于零。当b等于零时,那么它与你最初在'out'参数中给出的值无关。

+0

这应该是公认的答案。 – mrplants 2017-12-02 21:50:49

+0

FWIW我也很喜欢denis的回答。将所有答案合并成一个答案可能会很好。 – hlin117 2017-12-03 20:11:35

10

尝试分两步进行。先划分,然后更换。

with numpy.errstate(divide='ignore'): 
    result = numerator/denominator 
    result[denominator == 0] = 0 

numpy.errstate线是可选的,只是阻止告诉你关于除以零的“错误” numpy的,因为你已经打算这样做,和处理这种情况。

+4

你应该在np.errstate(divide ='ignore'):' – 2014-10-08 04:18:21

+0

@WarrenWeckesser Fair point的上下文中执行除法。我编辑了包含上下文的答案。如果他/她仍然需要通知,'divide''warn''也可能有用。 – 2014-10-09 00:38:03

+0

如果分母是标量,就不会工作 – denis 2016-02-29 09:36:47

2

您也可以替代基于inf,只有当阵列dtypes是花车,按this answer

>>> a = np.array([1,2,3], dtype='float') 
>>> b = np.array([0,1,3], dtype='float') 
>>> c = a/b 
>>> c 
array([ inf, 2., 1.]) 
>>> c[c == np.inf] = 0 
>>> c 
array([ 0., 2., 1.]) 
1

一个答案,我发现寻找一个相关的问题是操纵基于分母是否输出零或不是。

假设arrayAarrayB已被初始化,但arrayB有一些零。如果我们想要安全地计算arrayC = arrayA/arrayB,我们可以执行以下操作。

在这种情况下,每当我在小区中的一个具有通过零的鸿沟,我所述小区设置到等于myOwnValue,在这种情况下将是零

myOwnValue = 0 
arrayC = np.zeros(arrayA.shape()) 
indNonZeros = np.where(arrayB != 0) 
indZeros = np.where(arrayB = 0) 

# division in two steps: first with nonzero cells, and then zero cells 
arrayC[indNonZeros] = arrayA[indNonZeros]/arrayB[indNonZeros] 
arrayC[indZeros] = myOwnValue # Look at footnote 

脚注:回想起来,这条线是不必要的,因为arrayC[i]被实例化为零。但如果遇到这种情况,那么这个操作会做点什么。

32

建立在其他的答案,并提高对:

代码:

import numpy as np 

a = np.array([0,0,1,1,2], dtype='float') 
b = np.array([0,1,0,1,3], dtype='float') 

with np.errstate(divide='ignore', invalid='ignore'): 
    c = np.true_divide(a,b) 
    c[c == np.inf] = 0 
    c = np.nan_to_num(c) 

print('c: {0}'.format(c)) 

输出:

c: [ 0.   0.   0.   1.   0.66666667] 
+0

检查'0/0'以及'1/0'错误的好工作。 – hlin117 2015-08-20 04:31:13

35

大厦@Franck Dernoncourt的回答,固定-1/0:

def div0(a, b): 
    """ ignore/0, div0([-1, 0, 1], 0) -> [0, 0, 0] """ 
    with np.errstate(divide='ignore', invalid='ignore'): 
     c = np.true_divide(a, b) 
     c[ ~ np.isfinite(c)] = 0 # -inf inf NaN 
    return c 

div0([-1, 0, 1], 0) 
array([0, 0, 0]) 
+0

谢谢,我甚至没有用@Frank Dernoncourt的代码来捕捉这个bug。 – hlin117 2016-02-29 17:38:28

+0

嗨,我想做数组数学,我想0/0导致0,但我也想忽略np.NaN在我的计算以及。这会为此工作吗?另外,我正在努力理解。 c [〜np.isfinite(c)] = 0是做什么的?我从来没有在python中使用〜。它是为了什么?谢谢 – user20408 2016-05-17 14:41:28

+0

@ user20408,'〜'颠倒了numpy数组中的'True'和'False':'print〜np.array([True,False,False])''。 'c [〜np.isfinite(c)] = 0'意味着: 找到'c'是有限的位置,将这些位置反转为不与'〜'有限, 并且将非有限值设置为0. 另请参阅 http://stackoverflow.com/search?q=[numpy]+"boolean+indexing“ – denis 2016-05-20 09:07:26

10

的一行(抛出警告)

np.nan_to_num(array1/array2)