NumPy broadcasting: транслирование массивов в Python
В предыдущих руководствах вы узнали, как выполнять арифметические операции с массивами одинакового размера с помощью функций add(), subtract(), multiply() и divide() или операторов +, -, * и /.
- Что такое NumPy broadcasting?
- Правила транслирования NumPy
- 1) Транслирование NumPy на примере одного массива
- 2) Пример транслирования NumPy на оба массива
- 3) Broadcasting NumPy с примером ошибки
Что такое NumPy broadcasting?
Для выполнения арифметических операций с массивами различной формы NumPy использует метод Python, называемый broadcasting.
По определению, broadcasting (транслирование) — это набор правил применения арифметических операций над массивами различной формы. Вскоре мы подробно рассмотрим эти правила.
Перед этим давайте рассмотрим несколько простых примеров транслирования. Например, вы можете использовать оператор + для добавления числа в массив следующим образом:
import numpy as np a = np.array([1, 2, 3]) b = a + 1 print(b)
Выход:
[2 3 4]
В этом примере число один добавляется к одномерному массиву с помощью оператора +. Внутренне NumPy добавляет число 1 к каждому элементу массива. Этот метод называется вещанием.
Другими словами, NumPy передает число один по первому измерению, чтобы оно соответствовало форме одномерного массива.
Концептуально вы можете рассматривать приведенную выше трансляцию как эквивалентную следующей:
import numpy as np a = np.array([1, 2, 3]) b = a + np.array([1, 1, 1]) print(b)
Таким образом, добавление числа один в одномерный массив похоже на дублирование числа один в другой одномерный массив [1, 1, 1] и добавление этого массива в массив:
Однако NumPy транслирует номер один, не дублируя его. Благодаря этому NumPy может эффективно управлять вычислениями и ускорять их в большинстве случаев.
Аналогичным образом вы можете добавить 1D-массив к 2D-массиву, используя такую трансляцию:
import numpy as np a = np.array([ [1, 2, 3], [4, 5, 6] ]) b = np.array([10, 20, 30]) c = a + b print(c)
Выход:
[[11 22 33] [14 25 36]]
В этом примере NumPy транслирует одномерный массив b по второму измерению, чтобы он соответствовал форме массива a.
Правила транслирования NumPy
NumPy определяет набор правил транслирования:
- Правило 1: если два массива имеют разные размеры, он дополняет те из них, которые находятся в левой части формы массива с меньшими размерностями.
- Правило 2: если два измерения массивов не совпадают ни в одном измерении, массив с формой, равной единице в этом измерении, растягивается (или транслируется), чтобы соответствовать форме другого массива.
- Правило 3: если какое-либо измерение двух массивов не равно и ни одно из них не равно единице, NumPy выдает ошибку.
Давайте приведем несколько примеров, чтобы понять эти правила.
1) Транслирование NumPy на примере одного массива
В следующем примере двумерный массив добавляется к одномерному массиву:
import numpy as np a = np.array([ [1, 2, 3], [4, 5, 6] ]) b = np.ones(3) c = a + b print(c)
Выход:
[[2. 3. 4.] [5. 6. 7.]]
В следующей таблице показаны формы a и b:
Множество | Форма |
---|---|
а | (2,3) |
b | (3,) |
По правилу 1, поскольку массив b имеет меньше измерений, NumPy дополняет один слева:
Множество | Форма |
---|---|
а | (2,3) |
b | (1,3) |
По правилу 2 первые размеры двух фигур не равны, NumPy растягивает(или транслирует) первое измерение массива b, чтобы оно совпадало:
Множество | Форма |
---|---|
а | (2,3) |
b | (2,3) |
Теперь размеры обоих массивов совпадают. Форма массива результатов:(2,3).
2) Пример транслирования NumPy на оба массива
Следующий пример иллюстрирует случай, когда NumPy передает оба массива:
import numpy as np a = np.array([ [1], [2], [3], ]) print(f"a shape: ", a.shape) b = np.array([1, 2, 3]) print(f"b shape: ", b.shape) c = a + b print(c) print(f"c shape: ", c.shape)
Выход:
a shape: (3, 1) b shape: (3,) [[2 3 4] [3 4 5] [4 5 6]] c shape: (3, 3)
В этом примере форма массивов a и b равна(3,1) и(3) соответственно.
Множество | Форма |
---|---|
а | (3,1) |
b | (3,) |
По правилу 1 NumPy дополняет форму b единицами:
Множество | Форма |
---|---|
а | (3,1) |
b | (1,3) |
По правилу 2 NumPy растягивает размеры обоих массивов a и b, чтобы они совпадали, поскольку они оба равны:
Множество | Форма |
---|---|
а | (3,3) |
b | (3,3) |
Результирующий массив имеет форму(3,3).
3) Broadcasting NumPy с примером ошибки
В следующем примере добавляются два несовместимых массива:
import numpy as np a = np.array([ [1, 2], [3, 4], [5, 6], ]) print(f"a shape: ", a.shape) b = np.array([1, 2, 3]) print(f"b shape: ", b.shape) c = a + b
Выдает следующую ошибку:
a shape: (3, 2) b shape: (3,) ValueError: operands could not be broadcast together with shapes(3,2)(3,)
В этом примере массивы a и b имеют следующую форму:
Множество | Форма |
---|---|
а | (3,2) |
b | (3,) |
По правилу 1 NumPy дополняет форму второго массива единицами:
Множество | Форма |
---|---|
а | (3,2) |
b | (1,3) |
По правилу 2 NumPy растягивает первое измерение массива b от 1 до 3, чтобы оно соответствовало:
Множество | Форма |
---|---|
а | (3,2) |
b | (3,3) |
По правилу 3 конечные фигуры не совпадают, поэтому NumPy выдает ошибку.