Я искал ошибки в программе, и я обнаружил, что он был произведен неожиданным поведением от Numpy ...Неожиданных Numpy/Py3k правила принуждения
При выполнении, например, простой арифметической операции на разном целочисленные типы, использующие Python3k и Numpy, как
(numpy.uint64) + (INT)
результат это ... numpy.float64
Вот пример:
v = numpy.array([10**16+1], dtype=numpy.uint64)
print(v[0])
v[0] += 1
print(v[0])
Он производит следующий результат:
10000000000000001
10000000000000000
который может быть весьма неожиданным, когда вы имеете дело с целыми числами, чтобы избежать ошибок округления ...
выше «проблема» легко может быть решена заменив 1 на numpy.uint64 (1), но я вижу много ошибок, исходящих из этого. Каковы правила и логика этой ситуации? Есть ли какая-либо документация о том, как в таком случае делаются принуждения? Я не мог найти его.
Раньше я думал, что вы могли бы иметь некоторое представление о принуждение с помощью .item(), но это еще больше вводит в заблуждение:
v = numpy.array([10**16+1], dtype=numpy.uint64)
print(type(v[0].item()))
v[0] = v[0].item() + 1
print(v[0])
производит
<class 'int'>
10000000000000001
10000000000000002
Так .item() преобразует numpy.uint64 в int, и если вы явно используете его в арифметической операции, он работает.
Я удивлен (но мне не хватает Numpy опыта, я думаю), что, когда 'а' соответствует Numpy конкретной DTYPE,
a.item() + 1
и
a + 1
не дают те же результаты ... и, таким образом, дают разные результаты при преобразовании обратно в numpy dtype.
(Используемая среда - это современное распределение Pyzo через IEP, если это имеет значение. Обычно я использую Python 2, но мне пришлось сделать пару тестов в Py3k, и это был удобный способ сделать . это)
Он отлично работает с 'DTYPE = np.int64' вместо' DTYPE = np.uint64' (как для Python 2 и 3, 1,6 и NumPy 1,9). Я действительно не понимаю, почему это происходит, звучит как ошибка ... Просто используйте 'np.int64', нет причин использовать' uint64', переполненный на '2⁶⁴ - 1' или' 2⁶³ - 1' в значительной степени то же самое для всех практических целей. – rth
Это интересно ... Действительно, это работает с 'dtype = np.int64' ... Не уверен, что это ошибка (хотя мне кажется, что это ошибка), так как« np.int32 + int »и' np .uint32 + int' оба преобразуются в 'np.int64', возможно, чтобы избежать переполнения. Почему 'np.int64 + int' становится' np.int64', а 'np.uint64 + int' становится' np.float64' все еще ускользает от меня. У меня много обходных решений, но я хотел бы знать, есть ли причина для этого, и где я могу это найти. Спасибо за комментарий ... – Koren
Вот соответствующая [проблема с numpy] (https://github.com/numpy/numpy/issues/5745), которая делает чувство на каком-то уровне, хотя оно все еще не очень интуитивное. – rth