Нашли ошибку?
среднийNumPy 2.5.3

Оси: axis и keepdims

Посчитать сумму, среднее или максимум по строкам или по столбцам — и не перепутать, что значат axis=0 и axis=1.

Нужно знать:Базовые агрегацииМногомерная индексация

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

Коротко

  • axis — номер оси, вдоль которой идёт вычисление. Эта ось исчезает из формы результата.
  • В двумерном массиве axis=0 идёт вниз по строкам → одно значение на каждый столбец; axis=1 идёт вдоль строки → одно значение на каждую строку.
  • axis=None (по умолчанию) — по всему массиву; axis=-1 — последняя ось; можно передать кортеж осей.
  • keepdims=True оставляет свёрнутую ось длиной 1 — результат удобно транслировать обратно на исходный массив.
  • Накопительные cumsum, cumprod форму не меняют, а без axis вытягивают массив в одну строку.

Синтаксис

a.sum(axis=0)                # по столбцам: (3, 4) → (4,)
a.sum(axis=1)                # по строкам:  (3, 4) → (3,)
a.mean(axis=1, keepdims=True)  # (3, 4) → (3, 1)
a.argmax(axis=1)             # индекс максимума в каждой строке
a.cumsum(axis=1)             # нарастающий итог, форма та же
a.sum(axis=(0, 2))           # сразу по нескольким осям

Параметры

ПараметрЧто делаетПо умолчанию
axisось или кортеж осей; отрицательные считаются с концаNone
keepdimsоставить свёрнутые оси длиной 1False

Примеры

Данные для примеровиспользуются во всех примерах ниже
# продажи: 3 магазина (строки) × 4 месяца (столбцы)
sales = np.array([[5, 3, 4, 6],
                  [2, 7, 1, 3],
                  [4, 4, 5, 2]])
Сумма по столбцам, строкам и всего
print(sales.sum(axis=0))    # по каждому месяцу (столбцу)
print(sales.sum(axis=1))    # по каждому магазину (строке)
sales.sum()                 # всё вместе
Вывод
[11 14 10 11]
[18 13 15]
np.int64(46)
keepdims: доля в сумме строки
row_total = sales.sum(axis=1, keepdims=True)
print(row_total.shape)
(sales / row_total).round(2)   # доля каждого месяца в продажах магазина
Вывод
(3, 1)
array([[0.28, 0.17, 0.22, 0.33],
       [0.15, 0.54, 0.08, 0.23],
       [0.27, 0.27, 0.33, 0.13]])
Где максимум в каждой строке и столбце
print(sales.argmax(axis=1))  # лучший месяц каждого магазина
sales.argmax(axis=0)         # лучший магазин каждого месяца
Вывод
[3 1 2]
array([0, 1, 2, 0])
Нарастающий итог
print(sales.cumsum(axis=1))  # нарастающий итог по месяцам; форма не меняется
sales.cumsum()               # без axis — массив вытягивается в строку
Вывод
[[ 5  8 12 18]
 [ 2  9 10 13]
 [ 4  8 13 15]]
array([ 5,  8, 12, 18, 20, 27, 28, 31, 35, 39, 44, 46])
Три оси: последняя и несколько сразу
cube = np.ones((2, 3, 4))
print(cube.sum(axis=-1).shape)       # последняя ось
cube.sum(axis=(0, 2)).shape          # сразу по двум осям
Вывод
(2, 3)
(3,)

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

«axis=0 — это по строкам?»

Путаница из-за слов: axis=0 сворачивает строки, поэтому ответ получается для каждого столбца. Проверка без запоминания: посмотрите на форму — из (3, 4) при axis=0 исчезает 3, остаётся (4,). В pandas смысл тот же: df.sum(axis=0) — сумма каждого столбца.

Оси, которой нет

Оси нумеруются с нуля: у двумерного массива только 0 и 1 (или −1 и −2).

axis=2 у двумерного массиваошибка: AxisError
sales.sum(axis=2)
Ошибка
AxisError: axis 2 is out of bounds for array of dimension 2