如何返回0除以0

我尝试在 python 中执行元素除法,但是如果遇到一个零,我需要商仅为零。

例如:

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


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

我总是可以在数据中使用 for 循环,但是为了真正利用 numpy 的优化,我需要除法函数在除零错误时返回0,而不是忽略错误。

除非我遗漏了什么,否则 Seterr ()似乎不能在出错时返回值。对于如何在设置自己的零错误除法时最大限度地利用 numpy,有人有其他建议吗?

149590 次浏览

试着分两步来做,先分组,然后换人。

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

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

您也可以基于 inf进行替换,只有当数组 dtype 为 float 时,如 这个答案所示:

>>> 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.])

我发现搜索相关问题的一个答案是根据分母是否为零来操纵输出。

假设已经初始化了 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]被实例化为零。但是如果是 myOwnValue != 0的情况,这个操作会做一些事情。

以其他答案为基础,并在此基础上不断改进:

密码:

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]

基于@Franck Dernoncourt 的回答,修正 -1/0和我在标量上的 bug:

def div0( a, b, fill=np.nan ):
""" a / b, divide by 0 -> `fill`
div0( [-1, 0, 1], 0, fill=np.nan) -> [nan nan nan]
div0( 1, 0, fill=np.inf ) -> inf
"""
with np.errstate(divide='ignore', invalid='ignore'):
c = np.true_divide( a, b )
if np.isscalar( c ):
return c if np.isfinite( c ) \
else fill
else:
c[ ~ np.isfinite( c )] = fill
return c

在 numpy v1.7 + 中,您可以利用 Ufuns的“ where”选项。您可以在一行中完成任务,并且不必处理 errstate 上下文管理器。

>>> 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]

在这种情况下,它在‘ where’b 不等于零的任何地方进行除法运算。当 b 等于零时,它与在‘ out’参数中最初给它的值保持不变。

不赞成(蟒蛇2解决方案) :

一行程序 (抛出警告)

np.nan_to_num(array1 / array2)

另一个值得一提的解决方案是:

>>> 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.])