Нежелательные округления при вычитании массивов в Python - PullRequest
4 голосов
/ 29 июля 2011

Я сталкиваюсь с проблемой, когда Python автоматически округляет очень маленькие числа (меньше 1e-8) при вычитании массива из одного числа с плавающей запятой. Возьмите этот пример:

 import numpy as np
 float(1) - np.array([1e-10, 1e-5])

Есть мысли о том, как заставить Python не округляться? Это заставляет меня делить на ноль в некоторых случаях и становится проблемой. Та же проблема возникает при вычитании из массива numpy.

Ответы [ 2 ]

6 голосов
/ 29 июля 2011

По большей части, вас просто обманывают repr массивов numy.

Рассмотрите приведенный выше пример:

import numpy as np  
x = float(1) - np.array([1e-10, 1e-5]) 
print x
print x[0]
print x[0] == 1.0

Это дает:

[ 1.      0.99999 ]
0.99999999999
False

Таким образом, первый элемент на самом деле не равен нулю, это просто симпатичная печать массивов, которые показывают это таким образом.

Это может контролироваться numpy.set_printoptions.

Конечно, numpy по своей сути использует поплавки с ограниченной точностью.Суть numpy в том, чтобы быть контейнером с эффективным использованием памяти для массивов схожих данных, поэтому в numpy нет эквивалента классу decimal.

Однако 64-разрядные операции с плавающей точкой имеют приличный диапазон точности,Вы не столкнетесь с большим количеством проблем с 1e-10 и 1e-5.Если вам нужно, есть также numpy.float128 dtype, но операции будут намного медленнее, чем использование нативных операций с плавающей запятой.

1 голос
/ 29 июля 2011

Полагаю, все, что зависит от обработки очень маленьких чисел с плавающей точкой, Python и базовых библиотек C, которые в определенный момент теряют точность.

Если вам нужен такой уровень точности, имхо, вы должны полагаться на что-то другое, например, дробные числа и т. Д.

Я не знаю, есть ли уже что-то, чтобы справиться с этим, но если бы вам удалось представить эти числа по-другому (например, 1/10000000000 и 1/100000), а затем вычислить результат с плавающей запятой только при В конце всех вычислений вам следует избегать всех этих проблем.

(Конечно, вам нужен некоторый класс, который автоматически обрабатывает дробные вычисления, чтобы избежать необходимости переопределения формул и т. Д.)

...