python arrays numpy error-handling divide-by-zero

python - Cómo devolver 0 con dividir por cero



arrays numpy (8)

Estoy tratando de realizar una división sabia de elementos en python, pero si se encuentra un cero, necesito que el cociente sea simplemente cero.

Por ejemplo:

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

Siempre podría usar un bucle for a través de mis datos, pero para utilizar realmente las optimizaciones de numpy, necesito la función de división para devolver 0 al dividir por cero errores en lugar de ignorar el error.

A menos que me falte algo, no parece numpy.seterr() puede devolver valores tras errores. ¿Alguien tiene alguna otra sugerencia sobre cómo podría obtener lo mejor de numpy mientras establezco mi propia división por manejo de cero errores?


Aprovechando las otras respuestas y mejorando:

Código:

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

Salida:

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


Basándose en la respuesta de @Franck Dernoncourt, arreglando -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])


En numpy v1.7 +, puede aprovechar la opción "where" para ufuncs . Puede hacer las cosas en una línea y no tiene que lidiar con el administrador de contexto de estado.

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

En este caso, realiza el cálculo de división en cualquier lugar ''donde'' b no es igual a cero. Cuando b es igual a cero, entonces permanece sin cambios desde el valor que originalmente le dio en el argumento ''out''.


Intenta hacerlo en dos pasos. División primero, luego reemplazar.

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

La línea numpy.errstate es opcional, y solo evita que numpy le informe sobre el "error" de dividir por cero, ya que ya tiene la intención de hacerlo y manejar ese caso.


Otra solución que vale la pena mencionar:

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


También puede reemplazar en base a inf , solo si los tipos de matriz son flotantes, según esta respuesta :

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


Una respuesta que encontré al buscar una pregunta relacionada fue manipular la salida en función de si el denominador era cero o no.

Supongamos que se han inicializado arrayA y arrayB , pero arrayB tiene algunos ceros. Podríamos hacer lo siguiente si queremos calcular arrayC = arrayA / arrayB forma segura.

En este caso, cada vez que tengo una división entre cero en una de las celdas, configuro la celda para que sea igual a myOwnValue , que en este caso sería cero

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

Nota al pie: en retrospectiva, esta línea es innecesaria de todos modos, ya que arrayC[i] se instancia a cero. Pero si fuera el caso de que myOwnValue != 0 , esta operación haría algo.


One-liner (advertencia de lanzamiento)

np.nan_to_num(array1 / array2)