Вопрос по numpy, python – Python Numpy Arange неожиданные результаты

16

Я использую функцию arange для определения итераций цикла for и получаю неожиданные результаты.

<code>i = arange(7.8,8.4,0.05)
print i
</code>

выдает следующее:

<code>[ 7.8   7.85  7.9   7.95  8.    8.05  8.1   8.15  8.2   8.25  8.3   8.35 8.4 ]
</code>

все же используя стоп-значение 8,35 следующим образом

<code>i = arange(7.8,8.35,0.05)
</code>

дает следующее

<code>[ 7.8   7.85  7.9   7.95  8.    8.05  8.1   8.15  8.2   8.25  8.3 ]
</code>

Но я хочу, чтобы мой диапазон закончился на 8,35! Я знаю, что могу использовать значение остановки & gt; 8,35 и & lt; 8.4 чтобы достичь моего результата, но почему он отличается и, на мой взгляд, противоречив?

Редактировать: я использую версию 2.7

Я использую 2.7! smashtastic
Простой способ избежать этих проблем - использоватьarrange=(7.8,8.351,0.05) Thiru
Какую версию Python вы используете? Brendan Wood

Ваш Ответ

4   ответа
3

    For floating point arguments, the length of the result is
    ``ceil((stop - start)/step)``.  Because of floating point overflow,
    this rule may result in the last element of `out` being greater
    than `stop`.

для python 2.7 преобразования на числа с плавающей точкой и строки теперь корректно округляются на большинстве платформ.

в 2.7

>>> float(repr(2.3))
2.3

в 2.6

>>> float(repr(2.3))
2.2999999999999998
20

numpy.arange делает то же самое, что и PythonrangeОн не включает в себя «конечную точку». (например.range(0, 4, 2) даст[0,2] вместо[0,2,4])

Однако для шагов с плавающей запятой ошибки округления накапливаются, и иногда последнее значение фактически включает конечную точку.

Как отмечено в документации дляarange:

When using a non-integer step, such as 0.1, the results will often not be consistent. It is better to use linspace for these cases.

numpy.linspace генерирует указанное количество точек между начальной и конечной точкой. Кстати, он включает конечные точки по умолчанию.

это ясно в документах, но это не делает numpy.arange полезным, не так ли?
привет - я пытался найти справочную документацию онлайн для linspace, но она странно пуста ... у вас есть подходящая ссылка? smashtastic
docs.scipy.org/doc/numpy-1.6.0/reference/generated/…  С другой стороны, вы можете просто сделатьpydoc numpy.linspace или если вы работаете с интерпретатором Pythonhelp(numpy.linspace)или вipythonэто простоnumpy.linspace?.
2

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

import numpy as np
def my_arange(a, b, dr, decimals=6):
    res = [a]
    k = 1
    while res[-1] < b:
        tmp = round(a + k*dr,decimals)
        if tmp > b:
            break   
        res.append(tmp)
        k+=1

    return np.asarray(res)
это было полезно. Спасибо!
9

это связано с ограничениями чисел с плавающей запятой. Из-за точности станка невозможно идеально хранить все мыслимые значения в виде числа с плавающей запятой. Например:

>>> 8.4
8.4000000000000004
>>> 8.35
8.3499999999999996

Таким образом, 8,4 как плавающая точка немного больше, чем фактическое значение 8,4, а 8,35 как плавающая точка чуть меньше.

numpy.arange также не может правильно обработать это в Python 2.7.
Я думаю, это объясняет то, что я вижу - спасибо! smashtastic
это похоже на вывод с Python 2.6, но с 2.7, & gt; & gt; & gt; & gt; 8.4 получается как 8.4
Так и есть, это интересно. Похоже, что они изменили способ печати чисел с плавающей запятой, хотя основное число все еще остается неизменным (слегка неправильным), что можно увидеть, сравнив шестнадцатеричные значения для чисел с плавающей запятой в Python 2.6 и 2.7.

Похожие вопросы