Нашли ошибку?
базовыйNumPy 2.5.3

Типы данных и astype

Какой тип у элементов, как его сменить и почему целые числа в массиве могут молча переполниться.

Нужно знать:Создание массивовАтрибуты массива

Содержание статьи

Коротко

  • Все элементы массива одного типа (dtype). По умолчанию целые — int64, дробные — float64.
  • a.astype(тип) возвращает новый массив нужного типа. Из float в int дробная часть отбрасывается (к нулю), а не округляется.
  • Целые в массиве переполняются молча: int8 после 127 переходит в −128. Пределы типа — np.iinfo, для float — np.finfo.
  • Запись в массив приводит значение к его типу: 9.9 в целом массиве станет 9, а NaN туда не записать.
  • Число Python не расширяет тип массива (правила NEP 50 в NumPy 2): float32 + 3.0 остаётся float32.

Синтаксис

a.dtype                  # dtype('int64')
a.astype(np.float32)     # или "float32", float, int, bool, str
np.array(data, dtype=np.int16)
np.iinfo(np.int8)        # min, max для целых
np.finfo(np.float64)     # eps, max, точность для дробных

Параметры

ПараметрЧто делаетПо умолчанию
dtypeновый тип: объект NumPy (np.int32), строка ("int32") или тип Python (int, float, bool)обязательный
copyFalse — не копировать, если тип уже совпадаетTrue
Тип Что хранит Байт
bool True / False 1
int8, int16, int32, int64 целые со знаком 1, 2, 4, 8
uint8 … uint64 целые без знака 1 … 8
float32, float64 дробные 4, 8
complex128 комплексные 16
<U5 строки Unicode до 5 символов 20

Примеры

Тип определяется по данным
for data in ([1, 2, 3], [1.0, 2], [True, False], ["да", "нет"]):
    print(np.array(data).dtype)
Вывод
int64
float64
bool
<U3
Смена типа
prices = np.array([19.99, 5.5, -2.7])
print(prices.astype(int))        # дробная часть отбрасывается, к нулю
print(prices.astype(np.float32))
np.array(["1.5", "2", "-3"]).astype(float)
Вывод
[19  5 -2]
[19.99  5.5  -2.7 ]
array([ 1.5,  2. , -3. ])
Пределы типов
print(np.iinfo(np.int8).min, np.iinfo(np.int8).max)
print(np.iinfo(np.int64).max)
np.finfo(np.float32).eps
Вывод
-128 127
9223372036854775807
np.float32(1.1920929e-07)

Подводные камни

Переполнение целых без ошибки

Арифметика над массивом целых не проверяет выход за пределы. Для данных, которые могут вырасти (суммы, произведения), берите int64 или float64.

int8 после 127
level = np.array([120, 127], dtype=np.int8)
level + 10                       # вышли за 127 — значения «перевернулись»
Вывод
array([-126, -119], dtype=int8)

Запись в массив меняет значение

Дробь в целом массиве
counts = np.array([1, 2, 3])
counts[0] = 9.9                  # массив целый — дробь отброшена
counts
Вывод
array([9, 2, 3])
NaN в целом массивеошибка: ValueError
counts = np.array([1, 2, 3])
counts[0] = np.nan
Ошибка
ValueError: cannot convert float NaN to integer

Если нужны пропуски, массив должен быть дробным: np.array([1, 2, 3], dtype=float).

Число Python больше не расширяет тип

float32 плюс число Python
x = np.float32(3) + 3.0
x.dtype
Вывод
dtype('float32')
Число не помещается в тип массиваошибка: OverflowError
np.array([100], dtype=np.int8) + 200
Ошибка
OverflowError: Python integer 200 out of bounds for int8