Коротко
- Данные массива лежат в памяти одним блоком. Форма и strides говорят, как по нему ходить: на сколько байт сдвинуться, чтобы перейти к следующему элементу по каждой оси.
- C-порядок (по умолчанию) — строка за строкой; F-порядок (Fortran) — столбец за столбцом.
- Транспонирование, срезы с шагом,
broadcast_toменяют только strides — поэтому они бесплатны и дают представления. flags["C_CONTIGUOUS"]показывает, лежат ли элементы подряд в порядке C. Некоторые операции (ravel,reshape, передача в C-библиотеки) для несплошных массивов копируют данные.- Проход вдоль последней оси C-массива быстрее, чем вдоль первой: элементы идут подряд.
Синтаксис
a.strides # (байт по оси 0, байт по оси 1, …)
a.flags["C_CONTIGUOUS"], a.flags["F_CONTIGUOUS"]
np.ascontiguousarray(a) # копия в порядке C, если нужно
np.asfortranarray(a) # копия в порядке F, если нужно
np.zeros((3, 4), order="F")Примеры
m = np.arange(12, dtype=np.int64).reshape(3, 4)print(m.strides) # байт до следующей строки и до следующего столбца
m.T.strides # транспонирование только меняет strides местамиВывод
(32, 8) (8, 32)
print(m.flags["C_CONTIGUOUS"], m.flags["F_CONTIGUOUS"])
m.T.flags["C_CONTIGUOUS"], m.T.flags["F_CONTIGUOUS"]Вывод
True False (False, True)
f = np.asfortranarray(m) # те же значения, в памяти по столбцам
print(f.strides)
np.array_equal(f, m)Вывод
(8, 24) True
every_other = m[:, ::2]
print(every_other.strides) # шаг по столбцам вдвое больше
every_other.flags["C_CONTIGUOUS"] # данные идут с пропускамиВывод
(32, 16) False
c = np.ascontiguousarray(m.T) # копия в порядке C
c.flags["C_CONTIGUOUS"], np.shares_memory(c, m)Вывод
(True, False)
Подводные камни
ravel и reshape иногда копируют
Для несплошного массива (например, транспонированного) вытянуть элементы в строку без копии нельзя, и ravel молча копирует. Если важно, чтобы копии не было, используйте a.reshape(-1, copy=False) — он упадёт вместо копирования.
print(np.shares_memory(m.ravel(), m)) # C-массив вытягивается без копии
np.shares_memory(m.T.ravel(), m) # транспонированный — только с копиейВывод
True False