np.arange не работает должным образом с аргументами с плавающей запятой - PullRequest
0 голосов
/ 02 декабря 2018

Попробуйте это:

import numpy as np
np.arange(0,3*0.1,0.1)

Вывод будет: массив ([0., 0.1, 0.2, 0.3])

Это невероятно, потому что для np.arange 'генерируются значенияв течение полуоткрытого интервала [начало, остановка) '.Я пробовал другие числа и обнаружил, что только кратные 3 вызовут такое явление:

np.arange(0,2*0.1,0.1).shape
# 2
np.arange(0,3*0.1,0.1).shape
# 4
np.arange(0,4*0.1,0.1).shape
# 4
np.arange(0,5*0.1,0.1).shape
# 5
np.arange(0,6*0.1,0.1).shape
# 7

Я сейчас в замешательстве.Кто-нибудь может мне помочь?

1 Ответ

0 голосов
/ 02 декабря 2018

Проблема в вашей конечной точке: 3 * 0.1, которая не считается равной 0.3 (помните, что Python и NumPy используют арифметику с плавающей запятой , где некоторые числа, то есть 0.1, не могут быть представленыточно).

>>> 3 * 0.1
0.30000000000000004
>>> 0.3  
0.3  # or more exactly 0.299999999999999988897769753748...
>>> 3 * 0.1 == 0.3
False

Так что не удивительно, что 0.3 включен, потому что конечная точка (очень немного) больше.

Обратите внимание, что numpy.arange также содержит формулу, сколько элементов будет в массиве результатов:

ceil((stop - start)/step

>>> (3 * 0.1 - 0)/0.1
3.0000000000000004
>>> ceil(_)
4

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

>>> import numpy as np
>>> np.arange(0, 3, 1) / 10
array([0. , 0.1, 0.2])

Или функция numpy.linspace, которая предлагает дополнительные параметры для значений с плавающей запятой:

>>> import numpy as np
>>> np.linspace(0.0, 3 * 0.1, 3, endpoint=False)
array([0. , 0.1, 0.2])
...