широковещательные массивы в numpy

Я получил массив и преобразовал его в следующие размеры: (-1,1,1,1) и (-1,1):

 Array A:
[-0.888788523827  0.11842529285   0.319928774626  0.319928774626  0.378755429421  1.225877519716  3.830653798838]

A.reshape(-1,1,1,1):
[[[[-0.888788523827]]]


 [[[ 0.11842529285 ]]]


 [[[ 0.319928774626]]]


 [[[ 0.319928774626]]]


 [[[ 0.378755429421]]]


 [[[ 1.225877519716]]]


 [[[ 3.830653798838]]]]

A.reshape(-1,1):
[[-0.888788523827]
 [ 0.11842529285 ]
 [ 0.319928774626]
 [ 0.319928774626]
 [ 0.378755429421]
 [ 1.225877519716]
 [ 3.830653798838]]

Затем я сделал вычитание, и появилась широковещательная передача, поэтому моя результирующая матрица имеет размер 7x1x7x1.

Мне трудно представить себе промежуточный этап того, что делает вещание. Я имею в виду, что не могу представить, какие элементы массивов повторяются и как они выглядят при трансляции. Может ли кто-нибудь пролить свет на эту проблему, пожалуйста?


person Monica    schedule 15.07.2018    source источник
comment
Трудно обернуть голову такими массивами громоздкой формы. Возьмем небольшой пример и попробуем понять из него   -  person kmario23    schedule 15.07.2018


Ответы (1)


In [5]: arr = np.arange(4)
In [6]: A = arr.reshape(-1,1,1,1)
In [7]: B = arr.reshape(-1,1)
In [8]: C = A + B
In [9]: C.shape
Out[9]: (4, 1, 4, 1)
In [10]: A.shape
Out[10]: (4, 1, 1, 1)
In [11]: B.shape
Out[11]: (4, 1)

Есть 2 основных правила вещания:

  • расширить размеры, чтобы соответствовать - добавив размеры размера 1 в начале
  • отрегулируйте все размеры размера 1, чтобы они соответствовали

Итак, в этом примере:

 (4,1,1,1) + (4,1)
 (4,1,1,1) + (1,1,4,1)    # add 2 size 1's to B
 (4,1,4,1) + (4,1,4,1)    # adjust 2 of the 1's to 4
 (4,1,4,1)

Первый шаг, пожалуй, самый запутанный. (4,1) расширяется до (1,1,4,1), а не (4,1,1,1). Правило предназначено для того, чтобы избежать двусмысленности - путем последовательного расширения, не обязательно того, что человек может интуитивно хотеть.

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

 (4,) and (3,)
 (1,4) and (3,1)  or (4,1) and (1,3)
 (3,4)            or (4,3)
 confusion

Правило требует, чтобы программист выбрал, какое из них разворачивается вправо (4,1) или (3,1). numpy может затем однозначно добавить другой.


Для более простого примера:

In [22]: A=np.arange(3).reshape(-1,1)
In [23]: B=np.arange(3)
In [24]: C = A+B   (3,1)+(3,) => (3,1)+(1,3) => (3,3)
In [25]: C
Out[25]: 
array([[0, 1, 2],
       [1, 2, 3],
       [2, 3, 4]])
In [26]: C.shape
Out[26]: (3, 3)

[0,2,4] присутствуют, но по диагонали C.

При таком вещании получается своего рода outer сумма:

In [27]: np.add.outer(B,B)
Out[27]: 
array([[0, 1, 2],
       [1, 2, 3],
       [2, 3, 4]])
person hpaulj    schedule 15.07.2018
comment
Благодарю вас! Я понял этот момент. Хотя я не понимаю, как растягиваются столбцы и строки. Я взял более простой пример. arr = np.arange(3), A = arr.reshape(-1,1,1), B=arr.reshape(-1,1), и результирующий C отличается от ожидаемого. Я думал, что это должен быть массив с элементами 0,2,4, но ошибся. - person Monica; 15.07.2018
comment
Я добавил более простой пример. - person hpaulj; 15.07.2018