16

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

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

i = arange(7.8,8.4,0.05)
print i

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

[ 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 ]

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

i = arange(7.8,8.35,0.05)

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

[ 7.8   7.85  7.9   7.95  8.    8.05  8.1   8.15  8.2   8.25  8.3 ]

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

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

  • это ясно в документах, но это не делает numpy.arange полезным, не так ли?

    от
  • привет - я пытался найти справочную документацию онлайн для linspace, но она странно пуста ... у вас есть подходящая ссылка?

    от smashtastic
  • docs.scipy.org/doc/numpy-1.6.0/reference/generated/…  С другой стороны, вы можете просто сделатьpydoc numpy.linspace или если вы работаете с интерпретатором Pythonhelp(numpy.linspace)или вipythonэто простоnumpy.linspace?.

    от
  • это похоже на вывод с Python 2.6, но с 2.7, & gt; & gt; & gt; & gt; 8.4 получается как 8.4

    от
  • Так и есть, это интересно. Похоже, что они изменили способ печати чисел с плавающей запятой, хотя основное число все еще остается неизменным (слегка неправильным), что можно увидеть, сравнив шестнадцатеричные значения для чисел с плавающей запятой в Python 2.6 и 2.7.

    от
  • numpy.arange также не может правильно обработать это в Python 2.7.

    от
  • Я думаю, это объясняет то, что я вижу - спасибо!

    от smashtastic
  • это было полезно. Спасибо!

    от
  • Простой способ избежать этих проблем - использоватьarrange=(7.8,8.351,0.05)

    от Thiru
  • Какую версию Python вы используете?

    от Brendan Wood
  • Я использую 2.7!

    от smashtastic
  • 3

    с помощью функции Arange говорит

        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
    

  • 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)
    

  • 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 генерирует указанное количество точек между начальной и конечной точкой. Кстати, он включает конечные точки по умолчанию.

  • 9

    Возможно

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

    >>> 8.4
    8.4000000000000004
    >>> 8.35
    8.3499999999999996
    

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