2016-01-07 3 views
1

После того, как вы немного поработали, я все еще боюсь с делениями на ноль в numpy. Я ошеломлен противоречием сообщить сразу:Numpy, деление на ноль: два разных результата для одной и той же операции

from numpy import * 

seterr(all='ignore') # Trying to avoid ZeroDivisionError, but unsuccessful. 

def f(x) : 
    return 1./(x-1.) 

При этом, когда я исполняю f(1.), я получаю ZeroDivisionError: float division by zero.

Однако, когда я определяю z = array([ 1., 1. ]) и выполнить f(z), я не получаю сообщение об ошибке, но array([ inf, inf]).

Как вы можете видеть, между обоими выходами существует противоречие. My первый вопрос - это почему.

В идеале, я хотел бы получить inf как вывод f(1.), или не менее nan, но не ошибку (и, следовательно, остановку расчета). Мой второй вопрос - как это сделать. Обратите внимание на мою неудачную попытку, используя seterr.

+0

Разве это не только, что в первом случае вы воздействующего на целое число , а во втором вы работаете с массивом numpy? Это разные вещи, и поведение будет отличаться в зависимости от того, как операции определены для каждого. Я думаю, что если вам нужен последовательный вывод, вам нужно будет кормить функции согласованных типов ввода или, по крайней мере, типы, которые ведут себя одинаково под операциями. – JCVanHamme

ответ

0

Numpy не участвует в вашей функции f. Вам нужно поймать ZeroDivisionError, если вы хотите изменить выход.деление

import numpy 

def f(x) : 
    try: 
     return 1./(x-1.) 
    except ZeroDivisionError: 
     return numpy.nan 

Или использовать Numpy в:

import numpy 

def f(x) : 
    return numpy.divide(1., (x-1.)) 

Или только передать Numpy типы в f:

import numpy 

def f(x) : 
    return 1./(x-1.) 

x = numpy.float_(1) 
print f(x) # prints inf 
+0

Он отлично работает, спасибо. Но представьте, что у меня есть много функций в моем скрипте, и я хочу, чтобы каждая функция вела себя так, не добавляя код, который вы предлагаете каждому из них. Вы знаете, если это возможно? – hereje

+0

Да, это так! Но вам нужно использовать numpy.divide(). Это даст вам 'inf' по умолчанию. Обновлен мой ответ. –

+0

Я нахожу ваше последнее предложение особенно полезным, поскольку с ним мне не нужно ничего менять в моей исходной функции 'f (x)' (в скрипте, с которым я имею дело, у меня много сложных функций, и я бы не стал как изменить каждую косую черту на 'numpy.divide'). Я имею в виду, что 'f' можно легко переопределить для вычисления' f (numpy.float_ (x)) ', и это выполняет задание. Большое спасибо за ваше редактирование! – hereje

2

1. является обычным поплавком Python, и эти рейзы исключают вместо использования nan/inf. Когда вы вызываете f(1.), numpy никак не участвует. Просто выполнение from numpy import * (или вызов функций numpy, таких как seterr) ничего не меняет о том, как работают обычные типы Python; это повлияет только на операции с объектами numpy, и вы получите только объекты numpy, если вы их явно создадите.

Когда вы сделать явно создать Numpy объект, как в вашем f(z) Например, вы привлекаете NumPy, которая имеет свои собственные типы, которые отличаются от основных типов Python. Примечательно, numpy числовые типы do использование nan/inf.

Насколько я знаю, нет никакого способа, чтобы получить обычный Python поплавки, чтобы начать возвращать nan или inf вместо повышения исключений, так что вы должны будете использовать NumPy скаляры вместо простых поплавков Python (как описано в this question) если вы хотите поддерживать как скалярные, так и векторные операции.

+0

'np.divide (1.0.0.0)' возвращает 'inf' с предупреждением. Можно ли каким-либо образом импортировать 'divide' из' numpy'? Это имеет смысл в первую очередь? –

+1

@AndrasDeak: вы получаете предупреждение, потому что вы все еще проходите в плавающих поплавках Python. Если вы это сделаете, например, 'np.divide (np.float64 (1.0), 0)", то вы не получите предупреждение. Если вы хотите, чтобы все произошло в numpy, вам нужно, чтобы ваши объекты были типами numpy, прежде чем вы начнете делать numpy math на них. (Или вы можете просто жить с предупреждением.) – BrenBarn

+1

@AndrasDeak: И да, вы можете импортировать 'divide' из numpy, но это не изменит, как работает оператор'/'на простых платах Python. Ничего, что может сделать numpy, сделает простой «1.0/0.0' работать по-другому. – BrenBarn

0

Похоже, что seterr предназначен для использования с типами Numpy; как его можно использовать с родным типом Python. С другой стороны, если вы: не должно происходить

f(np.array((1,))) 

Нет ошибок с seterr.

 Смежные вопросы

  • Нет связанных вопросов^_^