web-dev-qa-db-ja.com

ゼロ除算で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を返すdivide関数が必要です。

何かが足りない場合を除き、 numpy.seterr() はエラー時に値を返すことができるようには見えません。ゼロエラー処理による独自の除算を設定しながら、numpyを最大限に活用する方法について他の提案がありますか?

73
hlin117

Numpy v1.7 +では、 funcs の "where"オプションを利用できます。 1行で物事を行うことができ、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]

この場合、bがゼロに等しくない「どこ」でも分割計算を行います。 bがゼロに等しい場合、「out」引数で最初に指定した値から変更されません。

126
DStauffman

@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])
38
denis

他の答えに基づいて、改善してください:

コード:

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

ワンライナー(警告をスロー)

np.nan_to_num(array1 / array2)
14
Ulf Aslak

2段階で試してみてください。最初に部門、次に交換します。

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

numpy.errstate行はオプションであり、numpyがゼロ除算の「エラー」について通知しないようにします。これは、すでにそうするつもりであり、そのケースを処理するためです。

13
Pi Marillion

この回答 のように、配列dtypesがfloatの場合にのみ、infに基づいて置換することもできます。

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

言及する価値がある他のソリューション:

>>> 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.])
0
T. Gwen

関連する質問を検索して見つけた1つの答えは、分母がゼロかどうかに基づいて出力を操作することでした。

arrayAarrayBが初期化されているが、arrayBにゼロが含まれているとします。 arrayC = arrayA / arrayBを安全に計算したい場合、次のことができます。

この場合、セルの1つにゼロによる除算があるときはいつでも、セルを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の場合、この操作は何かをします。

0
hlin117