NumPy: понимание трансляции

Python

Введение

Вещание описывает, как NumPy вычисляет операции между массивами разных форм. Если используются матрица большего размера и матрица меньшего размера, матрица меньшего размера будет транслироваться для обеспечения правильной работы.

В этой статье подробно объясняется использование трансляции в NumPy на конкретных примерах.

базовая трансляция

В нормальных условиях необходимо работать с двумя массивами, поэтому каждый объект массива должен иметь соответствующее значение для расчета. Например следующий пример:

a = np.array([1.0, 2.0, 3.0])
b = np.array([2.0, 2.0, 2.0])
a * b
array([ 2.,  4.,  6.])

Но если вы используете функцию вещания Numpy, то количество элементов не обязательно должно точно соответствовать.

Например, мы можем сказать, что массив умножается на константу:

a = np.array([1.0, 2.0, 3.0])
>>> b = 2.0
>>> a * b
array([ 2.,  4.,  6.])

Следующий пример эквивалентен приведенному выше примеру, Numpy автоматически расширит b.

NumPy достаточно умен, чтобы использовать исходное скалярное значение без фактического создания копии, делая широковещательные операции максимально эффективными с точки зрения использования памяти и вычислений.

Код во втором примере более эффективен, чем код в первом примере, поскольку память меньше памяти в размноженном процессе (B скалярный, а не массив).

Правила вещания

Если обрабатываются два массива, NumPy будет сравнивать объекты двух массивов, начиная с последнего измерения, если размеры двух массивов удовлетворяют следующим двум условиям, мы считаем два массива совместимыми и с ними можно работать:

  1. Количество элементов в измерении одинаково
  2. Один из размеров равен 1.

Если два вышеуказанных условия не выполняются, будет выдано исключение: ValueError: операнды не могут быть переданы вместе.

Тот факт, что количество элементов в измерениях одинаково, не означает, что два массива должны иметь одинаковое количество измерений.

например цвет256x256x3Массивы, которые можно умножить на одномерный массив из 3-х элементов:

Image  (3d array): 256 x 256 x 3
Scale  (1d array):             3
Result (3d array): 256 x 256 x 3

При умножении количество элементов в измерении, равном 1, будет растянуто, чтобы совпадать с количеством элементов в другом измерении:

A      (4d array):  8 x 1 x 6 x 1
B      (3d array):      7 x 1 x 5
Result (4d array):  8 x 7 x 6 x 5

В приведенном выше примере 1 во втором измерении растягивается до 7, 1 в третьем измерении растягивается до 6, а 1 в четвертом измерении растягивается до 5.

Есть еще примеры:

B      (1d array):      1
Result (2d array):  5 x 4

A      (2d array):  5 x 4
B      (1d array):      4
Result (2d array):  5 x 4

A      (3d array):  15 x 3 x 5
B      (3d array):  15 x 1 x 5
Result (3d array):  15 x 3 x 5

A      (3d array):  15 x 3 x 5
B      (2d array):       3 x 5
Result (3d array):  15 x 3 x 5

A      (3d array):  15 x 3 x 5
B      (2d array):       3 x 1
Result (3d array):  15 x 3 x 5

Ниже приведены примеры несоответствий:

A      (1d array):  3
B      (1d array):  4 # trailing dimensions do not match

A      (2d array):      2 x 1
B      (3d array):  8 x 4 x 3 # second from last dimensions mismatched

Другой пример реального кода:

>>> x = np.arange(4)
>>> xx = x.reshape(4,1)
>>> y = np.ones(5)
>>> z = np.ones((3,4))

>>> x.shape
(4,)

>>> y.shape
(5,)

>>> x + y
ValueError: operands could not be broadcast together with shapes (4,) (5,)

>>> xx.shape
(4, 1)

>>> y.shape
(5,)

>>> (xx + y).shape
(4, 5)

>>> xx + y
array([[ 1.,  1.,  1.,  1.,  1.],
       [ 2.,  2.,  2.,  2.,  2.],
       [ 3.,  3.,  3.,  3.,  3.],
       [ 4.,  4.,  4.,  4.,  4.]])

>>> x.shape
(4,)

>>> z.shape
(3, 4)

>>> (x + z).shape
(3, 4)

>>> x + z
array([[ 1.,  2.,  3.,  4.],
       [ 1.,  2.,  3.,  4.],
       [ 1.,  2.,  3.,  4.]])

Вещание также предоставляет очень удобную операцию для получения внешнего произведения двух одномерных массивов:

>>> a = np.array([0.0, 10.0, 20.0, 30.0])
>>> b = np.array([1.0, 2.0, 3.0])
>>> a[:, np.newaxis] + b
array([[  1.,   2.,   3.],
       [ 11.,  12.,  13.],
       [ 21.,  22.,  23.],
       [ 31.,  32.,  33.]])

где [:, np.newaxiss] преобразует 1мерный массив в 4-мерный массив:

In [230]: a[:, np.newaxis]
Out[230]:
array([[ 0.],
       [10.],
       [20.],
       [30.]])

Эта статья была включена вwoohoo.floydpress.com/07-python-вы…

Самая популярная интерпретация, самая глубокая галантерея, самые краткие уроки и множество трюков, о которых вы не знаете, ждут вас!

Добро пожаловать, чтобы обратить внимание на мой официальный аккаунт: «Программируйте эти вещи», разбирайтесь в технологиях, лучше поймите себя!