Как вычесть вектор np из простой матрицы, если они имеют одинаковый размер ведущего размера: matrix.shape[0] = len(vector)?

Я хочу сделать это:

>>> v = np.array([1,1,3])
>>> M = np.ones((len(v), 2, 2))
>>> M - v

Так что v[0] вычитается из всех 4 значений в M [0],
v [1] вычитается из всех значений в M[1] и т. д.
Но я получаю ошибку

ValueError: operands could not be broadcast together with shapes (3,2,2) (3,)

Чтобы было ясно, я ищу что-то эквивалентное:

for i, n in enumerate(v): M[i] -= n
>>> M
array([[[ 0.,  0.],
    [ 0.,  0.]],

   [[ 0.,  0.],
    [ 0.,  0.]],

   [[-2., -2.],
    [-2., -2.]]])

Но без петли и эффективного времени

Дополнительные баллы за: что здесь происходит? Есть ли что-то неоднозначное в M - v? Если нет, то почему бы об этом не понять?

1 ответ

Решение

Основное правило широковещания заключается в том, что оно может автоматически добавлять измерение в начале, но вы должны явно добавить измерения в конце. Это позволяет избежать двусмысленности.

(3,) + (2,) => (3,2) or (2,3)???    ambiguous
(3,1) + (2,) => (3,1)+ (1,2) => (3,2)  

В твоем случае:

(3,2,2) (3,1,1) => (3,2,2)

M + v[:,None, None]

Я полагаю numpy мог бы сделать вывод, что (3,) можно транслировать только с (3,2,2), добавив измерения в конце. Но что, если M был (3,3,3)? Разработчики выбрали более простое, однозначное правило. Программистам не так сложно учиться и использовать это.

И нет никакого вреда, если добавить явное v[None,:] сам. Как и в случае с grouping (), явный маршрут часто добавляет ясности - программисту, если не интерпретатору.

Другие вопросы по тегам