Numpy: Неожиданный вывод от arange с dtype = int

Созданный на 5 мая 2020  ·  5Комментарии  ·  Источник: numpy/numpy


В [3]: np.arange (-3, 0, 0.5, dtype = int)
Out [3]: array ([- 3, -2, -1, 0, 1, 2])

Что ж, появление «1» и «2» было для нас немного неожиданным, поскольку оба числа немного больше 0.

Обычно это результат без dtype = int:

In [2]: np.arange(-3, 0, 0.5)                                                  
Out[2]: array([-3. , -2.5, -2. , -1.5, -1. , -0.5])
and we should get this with dtype=int:
In [4]: np.arange(-3, 0, 0.5).astype(int)                                      
Out[4]: array([-3, -2, -2, -1, -1,  0])

В руководстве по numpy указано:
dtype: dtype
Тип выходного массива. Если dtype не указан, выведите тип данных из других входных аргументов.

Таким образом, он должен влиять только на выходной массив, верно?

import numpy as np
print(np.arange(-3, 0, 0.5))
print(np.arange(-3, 0, 0.5, dtype=int))
print(np.arange(-3, 0, 0.5).astype(int))

Сообщение об ошибке:

Нет сообщения об ошибке ...

Информация о версии Numpy / Python:

Мы протестировали его под numpy «1.18.4» (чистый Python 3.7.6), а также «1.18.1» (Anaconda 3.7 с последним обновлением). Тот же результат.

1.18.4 3.7.6 (по умолчанию, 28 февраля 2020 г., 15:25:38)
[Clang 11.0.0 ( https://github.com/llvm/llvm-project.git eefbff0082c5228e01611f7

1.18.1 3.7.4 (по умолчанию, 13 августа 2019 г., 20:35:49)
[GCC 7.3.0]

00 - Bug numpy.core

Самый полезный комментарий

Получение значений, превышающих "стоп", действительно неприятно и немного неожиданно. Если arange не для float, вы можете проверить типы floaty numpy и вызвать исключение.

Кроме того, ручной ввод для dtype действительно позволяет пользователю ожидать чего-то вроде преобразования astype (dtype) только для вывода.

Как насчет:
1.) Исключение для нецелочисленных аргументов (например, start, stop, step).
2.) Проверьте, если stop> = start, иначе вызовите исключение.
3.) Приведите start, stop, step к int64 в начале функции.
4.) astype (dtype) вывод

Вместо 1.) вы можете перенаправить на linspace внутри диапазона, если обнаружен нецелочисленный ввод.

Все 5 Комментарий

О подобных ошибках сообщают снова и снова. По причинам, потерянным временем, я вполне уверен, что реализация arange выглядит примерно так:

def arange(start, stop, step, dtype):
    n = (start - stop) // step

    # dtype.type is a cast
    step = dtype.type(start + step) - dtype.type(start)

    # now do what you expect
    return [start + step*i for i in range(n)]

Может, стоит добавить этот псевдокод в документацию?

Да, этот код правильный (хотя не уверен на 100% в вычислении n ). Этот конкретный пример довольно экстремален и явно сломан, может, мы действительно сможем как-то от него избавиться?

arange постоянно ненавидят за возможно неверное определение, но я не могу придумать действительно хорошего предложения по его устранению (хотя, возможно, оно появилось раньше).
Не похоже, что мы можем хорошо изменить поведение arange для поплавков (возможно, исправления точности, но изменения конечной точки не являются хорошей IMO). Итак, нам нужно будет создать новую функцию ... Но тогда в большинстве случаев мне кажется, что linspace лучше, чем "правильный" диапазон с плавающей запятой, я не уверен, что исправленный диапазон с плавающей запятой действительно имеет слишком много вариантов использования.

В конце концов, я бы хотел хорошо продуманное предложение: / ...

Получение значений, превышающих "стоп", действительно неприятно и немного неожиданно. Если arange не для float, вы можете проверить типы floaty numpy и вызвать исключение.

Кроме того, ручной ввод для dtype действительно позволяет пользователю ожидать чего-то вроде преобразования astype (dtype) только для вывода.

Как насчет:
1.) Исключение для нецелочисленных аргументов (например, start, stop, step).
2.) Проверьте, если stop> = start, иначе вызовите исключение.
3.) Приведите start, stop, step к int64 в начале функции.
4.) astype (dtype) вывод

Вместо 1.) вы можете перенаправить на linspace внутри диапазона, если обнаружен нецелочисленный ввод.

Привет, я полный новичок в разработке открытого исходного кода. Подумал о том, чтобы попробовать. Как насчет этого фрагмента? @ eric-wieser

x = []
for i in range(start, stop):
    x.append(i)
    x.append(i+step)
print(np.array(x, dtype))

О подобных ошибках сообщают снова и снова. По причинам, потерянным временем, я вполне уверен, что реализация arange выглядит примерно так:

def arange(start, stop, step, dtype):
    n = (start - stop) // step

    # dtype.type is a cast
    step = dtype.type(start + step) - dtype.type(start)

    # now do what you expect
    return [start + step*i for i in range(n)]
Была ли эта страница полезной?
0 / 5 - 0 рейтинги