Могу ли я заставить массив numpy сохранять тип uint32?

Я хотел бы воспроизвести поведение C в Python, предположительно, используя numpy, но я столкнулся с этой проблемой:

>>> import numpy
>>> a = numpy.uint32(4294967295)
>>> type(a)
<class 'numpy.uint32'>
>>> a += 1
>>> a
4294967296
>>> type(a)
<class 'numpy.int64'>

В C с uint32 я бы получил 4294967295 + 1 = 0

Могу ли я заставить свой массив a оставаться массивом numpy.uint32, чтобы получить 0 в конце моего скрипта?

В связи с другим моим вопросом: Точно ли numpy воспроизводит все поведение C при обычных операциях?

Побитовое И с 0xFFFF_FFFF даст 0.

ikegami 18.03.2024 15:43

В данном конкретном случае вы можете использовать: a = (a+1).astype(numpy.uint32).

wohlstad 18.03.2024 15:45

Вы можете использовать a = np.uint32(a + 1)

Im Groot 18.03.2024 15:45

Имеет ли значение добавление np.uint32(1)? Python 1 по умолчанию становится int64.

hpaulj 18.03.2024 16:22

@hpaulj - Это сработало с предупреждением о переполнении.

tdelaney 18.03.2024 16:28

Мне кажется, что такое поведение нарушает собственную документацию numpy. Скаляры-массивы Основное преимущество использования скаляров-массивов заключается в том, что они сохраняют тип массива (Python может не иметь подходящего типа скаляра, например, int16). Таким образом, использование скаляров-массивов обеспечивает идентичное поведение между массивами и скалярами, независимо от того, находится ли значение внутри массива или нет. Обратите внимание, что arr = numpy.array([numpy.uint32(4294967295)]) тогда arr += 1 остается uint32.

tdelaney 18.03.2024 16:32

@tdelaney, см. мой дополнительный вопрос: stackoverflow.com/questions/78186300/….

wohlstad 19.03.2024 15:36

Возможно, вам будет интересно узнать, что недавно выпущенный NumPy 2.0 меняет правила продвижения типов, так что np.uint32 + int теперь создает uint32. См. numpy.org/doc/stable/… и редактирование моего ответа.

Nick ODell 17.06.2024 18:13
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
8
99
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Здесь вы не используете массив, и это важно, потому что NumPy не обязательно имеет одинаковое поведение между скаляром и массивом размером один.

Например, операции над массивом на месте никогда не изменяют тип массива.

Пример:

import numpy
a = numpy.array([4294967295], dtype='uint32')
a += 1
print(a)
print(a.dtype)

Выход:

[0]
uint32

Обновлено: NumPy 2.0 уже вышел, и одним из изменений является сохранение скалярного типа.

>>> import numpy as np
>>> a = np.uint32(4294967295)
>>> a += 1
<stdin>:1: RuntimeWarning: overflow encountered in scalar add
>>> a
np.uint32(0)
>>> type(a)
<class 'numpy.uint32'>

Поэтому одной из альтернатив является использование NumPy 2.0 или выше.

Другие вопросы по теме