2015-10-23 17 views
5

Ho il seguente 2D-array:NumPy sottrarre/aggiungere serie 1d dalla matrice 2D

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

e un altro 1D-array:

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

poi voglio calcolare qualcosa come

c = a - b 

con l'intento di ottenere:

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

ma invece ricevo il seguente messaggio di errore:

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

ho letto le regole di trasmissione, ma hanno ragione't ottenere qualsiasi più saggio. Potrei fare un workaround con for-loops o simili ma dovrebbe esserci un modo diretto. Grazie

+9

Do 'a - b [:, Nessuno] 'o' a - b [:, np.newaxis] ', converti' b' in un array 2D aggiungendo una dimensione e poi esegui la sottrazione. – Divakar

+2

@Divakar dovresti dare una risposta al tuo commento. –

+1

Non è una domanda di base come questa trattata prima su 'SO'? DUP-martello? :) – Divakar

risposta

13

È necessario convertire la matrice dell'array b to a (2, 1) shape, utilizzare None or numpy.newaxis nella tupla dell'indice. Ecco lo Indexing of Numpy array.

Si può fare così:

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 

uscita:

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

perfetto. Questo aiuta. Grazie – leofields

+0

@leofields: Se ti piace la mia risposta, dovresti accettare questo –

2

Come Divakar precisato nei commenti, è sufficiente aggiungere un nuovo asse per b.

vi consiglio di leggere di più su broadcasting che è molto spesso utile vectorize calcoli in NumPy: abbastanza interessante, a.transpose() - b non avrebbe sollevato un errore (avresti bisogno di trasporre di nuovo il risultato di ottenere l'output desiderato).

In questo calcolo, la forma del primo array è (3, 5) e b.shape è (5,). Quindi la forma di b corrisponde alla coda della forma di a e la trasmissione può avvenire. Questo non è il caso quando la forma del primo array è (5, 3), quindi l'errore che hai ottenuto.

Ecco alcuni test di runtime per confrontare le velocità dei risposte suggerite, con i tuoi valori per a e b: si può vedere che le differenze non sono davvero significativo

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' richiederebbe un'altra trasposizione per ottenere l'output desiderato, giusto? – Divakar

+0

@Divakar Sì, sì, non sto proponendo una soluzione, sto dicendo esplicitamente di usare il tuo. Poiché la tua soluzione era un commento, ho aggiunto il motivo per cui la trasmissione non funzionava. Se avessi postato una risposta, avrei commentato. –

+0

Stavo affermando per la completezza di questo post su come ottenere l'output e la forma desiderati :) – Divakar