关于python:如何以0除以返回0

How to return 0 with divide by zero

我试图在python中执行元素明智的划分,但如果遇到零,我需要商才为零。

例如:

1
2
3
4
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?


在numpy v1.7 +中,您可以利用ufunc的"where"选项。您可以在一行中执行操作,而无需处理errstate上下文管理器。

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

# If you don't pass `out` the indices where (b == 0) will be uninitialized!
>>> c = np.divide(a, b, out=np.zeros_like(a), where=b!=0)
>>> print(c)
[ 0.   0.   0.   1.   1.5]

在这种情况下,它在任何"b"不等于零的地方进行除法计算。当b确实等于零时,它在"out"参数中保持不变。


建立在@Franck Dernoncourt的答案上,修正-1 / 0:

1
2
3
4
5
6
7
8
9
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/0通过将invalid='ignore'添加到numpy.errstate()进行处理
  • 引入numpy.nan_to_num()np.nan转换为0

码:

1
2
3
4
5
6
7
8
9
10
11
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))

输出:

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


单线(投掷警告)

1
np.nan_to_num(array1 / array2)

尝试分两步完成。先划分,然后更换。

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

numpy.errstate行是可选的,只是阻止numpy告诉你除以零的"错误",因为你已经打算这样做,并处理这种情况。


您也可以基于inf进行替换,仅当数组dtypes是浮点数时,根据以下答案:

1
2
3
4
5
6
7
8
>>> 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
2
3
4
5
>>> a = np.array([1,2,3], dtype='float')
>>> b = np.array([0,1,3], dtype='float')
>>> b_inv = np.array([1/i if i!=0 else 0 for i in b])
>>> a*b_inv
array([0., 2., 1.])

我找到一个相关问题的答案就是根据分母是否为零来操纵输出。

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

在这种情况下,每当我在其中一个单元格中除以零时,我将单元格设置为等于myOwnValue,在这种情况下为零

1
2
3
4
5
6
7
8
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]被实例化为零。但如果是myOwnValue != 0的情况,这个操作会做点什么。