Как я могу уловить предупреждение numpy, как это исключение (не только для тестирования)?

Я должен сделать полином Лагранжа в Python для проекта, который я делаю. Я занимаюсь барицентрическим стилем, чтобы избежать использования явного for-loop, в отличие от разностного стиля разума Ньютона. Проблема в том, что мне нужно поймать деление на ноль, но Python (или, возможно, numpy) просто делает это предупреждение вместо обычного исключения.

Итак, мне нужно знать, как это сделать, это поймать это предупреждение, как если бы оно было исключением. На связанные с этим вопросы, которые я нашел на этом сайте, ответили не так, как мне было нужно. Вот мой код:

import numpy as np import matplotlib.pyplot as plt import warnings class Lagrange: def __init__(self, xPts, yPts): self.xPts = np.array(xPts) self.yPts = np.array(yPts) self.degree = len(xPts)-1 self.weights = np.array([np.product([x_j - x_i for x_j in xPts if x_j != x_i]) for x_i in xPts]) def __call__(self, x): warnings.filterwarnings("error") try: bigNumerator = np.product(x - self.xPts) numerators = np.array([bigNumerator/(x - x_j) for x_j in self.xPts]) return sum(numerators/self.weights*self.yPts) except Exception, e: # Catch division by 0. Only possible in 'numerators' array return yPts[np.where(xPts == x)[0][0]] L = Lagrange([-1,0,1],[1,0,1]) # Creates quadratic poly L(x) = x^2 L(1) # This should catch an error, then return 1. 

Когда этот код выполняется, вывод, который я получаю:

 Warning: divide by zero encountered in int_scalars 

Это предупреждение, которое я хочу поймать. Это должно происходить внутри понимания списка.

3 Solutions collect form web for “Как я могу уловить предупреждение numpy, как это исключение (не только для тестирования)?”

Кажется, что ваша конфигурация использует параметр print для numpy.seterr :

 >>> import numpy as np >>> np.array([1])/0 #'warn' mode __main__:1: RuntimeWarning: divide by zero encountered in divide array([0]) >>> np.seterr(all='print') {'over': 'warn', 'divide': 'warn', 'invalid': 'warn', 'under': 'ignore'} >>> np.array([1])/0 #'print' mode Warning: divide by zero encountered in divide array([0]) 

Это означает, что предупреждение, которое вы видите, не является реальным предупреждением, но это просто некоторые символы, напечатанные на stdout (см. Документацию для seterr ). Если вы хотите его поймать, вы можете:

  1. Используйте numpy.seterr(all='raise') который будет непосредственно поднимать исключение. Это, однако, изменяет поведение всех операций, поэтому это довольно большое изменение в поведении.
  2. Используйте numpy.seterr(all='warn') , который преобразует печатное предупреждение в реальное предупреждение, и вы сможете использовать вышеупомянутое решение, чтобы локализовать это изменение в поведении.

Как только у вас есть предупреждение, вы можете использовать модуль warnings для управления обработкой предупреждений:

 >>> import warnings >>> >>> warnings.filterwarnings('error') >>> >>> try: ... warnings.warn(Warning()) ... except Warning: ... print 'Warning was raised as an exception!' ... Warning was raised as an exception! 

Внимательно прочитайте документацию по filterwarnings так как она позволяет фильтровать только предупреждение, которое вы хотите, и имеет другие параметры. Я также рассматриваю возможность просмотра catch_warnings который является менеджером контекста, который автоматически сбрасывает исходную функцию filterwarnings :

 >>> import warnings >>> with warnings.catch_warnings(): ... warnings.filterwarnings('error') ... try: ... warnings.warn(Warning()) ... except Warning: print 'Raised!' ... Raised! >>> try: ... warnings.warn(Warning()) ... except Warning: print 'Not raised!' ... __main__:2: Warning: 

Чтобы добавить немного к ответу @ Bakuriu:

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

 import numpy as np a = np.r_[0] with np.errstate(divide='raise'): try: a / 0 # this gets caught and handled as an exception except FloatingPointError: print('oh no!') a / 0 # this prints a RuntimeWarning as usual 

Чтобы подробно остановиться на ответе @ Bakuriu выше, я обнаружил, что это позволяет мне поймать предупреждение во время выполнения аналогично тому, как я поймаю предупреждение об ошибке, красиво распечатав предупреждение:

 import warnings with warnings.catch_warnings(): warnings.filterwarnings('error') try: answer = 1 / 0 except Warning as e: print('error found:', e) 

Вероятно, вы сможете поиграть с размещением места warnings.catch_warnings () в зависимости от того, насколько большой из зонтика вы хотите бросить с ловушками ошибок таким образом.

  • Как преобразовать массив numpy в базу данных pandas?
  • Каков самый быстрый способ преобразования чередующегося целочисленного массива NumPy в complex64?
  • Почему существуют два np.int64s в numpy.core.numeric._typelessdata (почему numpy.int64 не numpy.int64?)
  • Почему numpy медленнее, чем python? Как сделать код более эффективным
  • Как построить файлы с numpy?
  • Чтение и сохранение произвольных целых чисел длины байта из файла
  • как разбить столбец кортежей в pandas dataframe?
  • Использование Python для программирования iOS
  • Python - лучший язык программирования в мире.