</>
Тема 5 из 6

Форма массивов

Одни и те же данные можно разложить по-разному: в строку, в таблицу 3×4 или 4×3, склеить с другими таблицами. В этой теме — инструменты, которые меняют форму массива, не трогая сами числа.

reshape — новая форма

import numpy as np

a = np.arange(12)
print(a.reshape(3, 4))
print(a.reshape(2, -1))    # -1: «посчитай сам» → (2, 6)

Элементы раскладываются по строкам: сначала заполняется первая строка, потом вторая. Произведение размеров должно совпадать с числом элементов.

Обратно в строку: ravel и flatten

m = np.array([[1, 2], [3, 4]])
print(m.ravel())      # [1 2 3 4]
print(m.flatten())    # [1 2 3 4] — то же, но всегда копия

Обе функции читают таблицу по строкам.

Транспонирование

.T меняет строки и столбцы местами: элемент (i, j) переходит в позицию (j, i).

m = np.array([[1, 2, 3],
              [4, 5, 6]])
print(m.T)
# [[1 4]
#  [2 5]
#  [3 6]]
print(m.T.shape)      # (3, 2)

Транспонирование часто нужно, когда данные записаны «не той стороной»: например, строки — это дни, а нужно анализировать по дням столбцами.

Новая ось

Иногда нужно превратить одномерный массив в строку или в столбец таблицы — например, для broadcasting:

a = np.array([1, 2, 3])
print(a.reshape(1, -1).shape)   # (1, 3) — строка
print(a.reshape(-1, 1).shape)   # (3, 1) — столбец
print(a[:, None].shape)         # (3, 1) — то же короче

Склейка

np.concatenate склеивает массивы вдоль существующей оси:

top = np.array([[1, 2], [3, 4]])
bottom = np.array([[5, 6]])
print(np.concatenate([top, bottom], axis=0))    # снизу: форма (3, 2)

right = np.array([[7], [8]])
print(np.concatenate([top, right], axis=1))     # справа: форма (2, 3)

По оси 0 должны совпадать столбцы, по оси 1 — строки. Иначе — ошибка all the input array dimensions ... must match.

Короткие синонимы: np.vstack([a, b]) — снизу, np.hstack([a, b]) — справа.

np.stack склеивает массивы одинаковой формы, добавляя новую ось:

x = np.array([1, 2, 3])
y = np.array([4, 5, 6])
print(np.stack([x, y]))          # строками: форма (2, 3)
print(np.stack([x, y], axis=1))  # столбцами: форма (3, 2)

Повторение

print(np.repeat([1, 2], 3))      # [1 1 1 2 2 2] — каждый элемент 3 раза
print(np.tile([1, 2], 3))        # [1 2 1 2 1 2] — весь массив 3 раза
print(np.tile([[1, 2]], (2, 2)))
# [[1 2 1 2]
#  [1 2 1 2]]

np.tile(a, (p, q)) выкладывает таблицу a блоками: p раз вниз и q раз вправо.

Итог

  • reshape(n, m) — новая форма, -1 — размер вычисляется сам;
  • ravel/flatten — обратно в одну строку (по строкам);
  • .T — транспонирование;
  • concatenate(..., axis=0/1) — склейка снизу/справа, vstack/hstack — короче;
  • stack — склейка с новой осью;
  • repeat — повтор элементов, tile — повтор массива блоками.