2015-10-23 3 views
5

У меня есть следующие 2D-массив:NumPy вычитать/добавить 1d массив из 2d массива

a = array([[ 1, 2, 3], 
      [ 4, 5, 6], 
      [ 7, 8, 9], 
      [10, 11, 12], 
      [13, 14, 15]]) 

и другой 1D-массив:

b = array([ 1, 2, 3, 4, 5]) 

, то я хочу, чтобы вычислить что-то вроде

c = a - b 

с целью получения:

c = array([[0, 1, 2], 
      [2, 3, 4], 
      [4, 5, 6], 
      [6, 7, 8], 
      [8, 9, 10]]) 

, но вместо этого я получаю сообщение об ошибке:

Traceback (most recent call last): 
    Python Shell, prompt 79, line 1 
ValueError: operands could not be broadcast together with shapes (5,3) (5,) 

Я прочитал правила вещания, но didn't получить любой мудрее. Я мог бы сделать обходной путь с for-loops или подобным, но должен быть прямой путь. Спасибо

+9

Do 'а - Ь [:, None] 'или' a - b [:, np.newaxis] ', который преобразует' b' в 2D-массив, добавляя измерение, а затем выполняйте вычитание. – Divakar

+2

@ Divakar вы должны сделать ответ из своего комментария. –

+1

Не является ли таким основным вопросом, как это описано выше на 'SO'? Dup-молот? :) – Divakar

ответ

13

Вам необходимо преобразовать массив b to a (2, 1) shape массив, используйте None or numpy.newaxis в индексном корте. Вот Indexing of Numpy array.

Вы можете сделать это:

import numpy 

a = numpy.array([[ 1, 2, 3], 
      [ 4, 5, 6], 
      [ 7, 8, 9], 
      [10, 11, 12], 
      [13, 14, 15]]) 

b = numpy.array([ 1, 2, 3, 4, 5]) 
c=a - b[:,None] 
print c 

Выход:

Out[2]: 
array([[ 0, 1, 2], 
     [ 2, 3, 4], 
     [ 4, 5, 6], 
     [ 6, 7, 8], 
     [ 8, 9, 10]]) 
+0

безупречный. Что помогает. Спасибо – leofields

+0

@leofields: Если вам нравится мой ответ, вы должны принять это значение –

2

Как указано Divakar в комментариях, просто добавьте новую ось b.

Я предлагаю вам прочитать больше о broadcasting, который очень часто бывает полезно векторизации вычислений в NumPy: достаточно интересно, a.transpose() - b не поднял бы ошибку (вам нужно перенести результат еще раз, чтобы получить свой желаемый результат).

В этом вычислении форма первого массива равна (3, 5), а b.shape - (5,). Таким образом, форма b соответствует хвосту формы a, и может случиться вещание. Это не тот случай, когда форма первого массива равна (5, 3), поэтому полученная ошибка.

Вот некоторые время выполнения тестов, чтобы сравнить скорость предложенных ответов, с вашими значениями a и b: вы можете видеть, что разница не очень значительная

In [9]: %timeit (a.T - b).T 
Out[9]: 1000000 loops, best of 3: 1.32 µs per loop 

In [10]: %timeit a - b[:,None] 
Out[10]: 1000000 loops, best of 3: 1.25 µs per loop 

In [11]: %timeit a - b[None].T 
Out[11]: 1000000 loops, best of 3: 1.3 µs per loop 
+0

'a.transpose() - b' потребуется другое транспонирование, чтобы получить желаемый результат, правильно? – Divakar

+0

@ Divakar Да, да, я не предлагаю решение, я прямо говорю вам использовать. Поскольку ваше решение было комментарием, я добавил, почему радиовещание не работает. Если бы вы отправили ответ, я бы прокомментировал это. –

+0

Я писал с целью полноты этого сообщения о том, как добраться до желаемого результата и формы :) – Divakar

Смежные вопросы