Неожиданные правила принуждения Numpy / Py3k
Я искал ошибку в программе и обнаружил, что она была вызвана неожиданным поведением Numpy...
При выполнении, например, простой арифметической операции над различными целочисленными типами с использованием 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, и если вы явно используете его в арифметической операции, он работает.
Я удивлен (но мне кажется, что у меня недостаточно опыта), когда 'a' соответствует конкретному типу dump,
a.item() + 1
а также
a + 1
не дает одинаковых результатов... и, следовательно, дает разные результаты при преобразовании обратно в numpy dtype.
(Используемая среда представляет собой современный дистрибутив Pyzo через IEP, если это имеет значение. Я обычно использую Python 2, но мне нужно было провести пару тестов в Py3k, и это был удобный способ сделать это.)
1 ответ
Как указано выше:
Работает нормально с:
dtype=np.int64
вместо:
dtype=np.uint64
оба для питона 2 и 3, numpy 1.6 и 1.9.
Просто используйте:
np.int64
нет причин использовать uint64
переполнен в 2⁶⁴ - 1
или же 2⁶³ - 1
это практически одно и то же для всех практических целей.
Рекомендации