NumPy: возврат 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, мне нужна функция divide для возврата 0 при делении на ноль ошибок вместо игнорирования ошибки.
Если я не упускаю что-то, это не кажется и NumPy.seterr() может возвращать значения по ошибкам. У кого-нибудь есть другие предложения о том, как я мог бы получить лучшее из numpy, установив свой собственный деление на нулевую обработку ошибок?
7 ответов
в numpy v1.7+, Вы можете воспользоваться опцией "где" для ufuncs. Вы можете делать вещи в одной строке, и вам не нужно иметь дело с контекстным менеджером 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".
основываясь на ответе @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/0
обработка путем добавленияinvalid='ignore'
tonumpy.errstate()
- вводим
numpy.nan_to_num()
преобразованиеnp.nan
to0
.
код:
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]
попробуйте сделать это в два шага. Сначала отдел, потом замена.
with numpy.errstate(divide='ignore'):
result = numerator / denominator
result[denominator == 0] = 0
на numpy.errstate
строка необязательна и просто не позволяет numpy сообщать вам об "ошибке" деления на ноль, так как вы уже намереваетесь это сделать и обрабатываете этот случай.
вы также можете заменить на основе inf
, только если dtypes массива поплавки, согласно ответ:
>>> 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.])
один ответ, который я нашел при поиске связанного вопроса, состоял в том, чтобы манипулировать выводом на основе того, равен ли знаменатель нулю или нет.
предположим arrayA
и arrayB
были инициализированы, но 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]
экземпляр равен нулю. Но если бы это было так ... --7-->, эта операция что-то сделает.