2015-10-23 18 views
5

Ich habe folgenden 2D-Array:numpy zu subtrahieren/hinzufügen 1d Array von 2D-Array

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

und anderen 1D-Array:

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

dann will ich so etwas wie

berechnen
c = a - b 

mit der Absicht zu bekommen:

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

sondern erhalte ich die Fehlermeldung:

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

ich die Rundfunk Regeln lesen, aber Artikel nicht klüger erhalten. Ich könnte einen Workaround mit for-Schleifen oder ähnlichem machen, aber es sollte einen direkten Weg geben. Danke

+9

Do 'a - b [:, None] 'oder' a - b [:, np.newaxis] ', das heißt, wandeln Sie' b' in ein 2D-Array um, indem Sie eine Dimension hinzufügen und dann subtrahieren. – Divakar

+2

@Divakar sollten Sie eine Antwort aus Ihrem Kommentar machen. –

+1

Ist eine grundlegende Frage wie diese nicht schon bei "SO" abgedeckt? Dup-Hammer? :) – Divakar

Antwort

13

Sie müssen das Array b to a (2, 1) shape Array konvertieren, verwenden Sie None or numpy.newaxis im Indextupel. Hier ist die Indexing of Numpy array.

Sie können es mögen:

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 

Ausgang:

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

perfekt. Das hilft. Danke – leofields

+0

@leofields: Wenn du meine Antwort magst, solltest du das akzeptieren –

2

Wie Divakar in den Kommentaren angegeben, nur eine neue Achse zu b hinzuzufügen.

Ich schlage vor, Sie mehr über broadcasting lesen, die sehr oft nützlich ist, Berechnungen in numpy vektorisieren: Interessanterweise würde a.transpose() - b kein Fehler ausgelöst hat (Sie müssen das Ergebnis wieder transponieren Sie die gewünschte Ausgabe zu erhalten).

In diesem Computer ist die Form des ersten Arrays (3, 5) und b.shape ist (5,). So entspricht die Form von b dem Schwanz der Form von a, und das Senden kann passieren. Dies ist nicht der Fall, wenn die Form des ersten Arrays (5, 3) ist, daher der Fehler, den Sie erhalten haben.

Hier sind einige Laufzeittests, die Geschwindigkeiten der vorgeschlagenen Antworten zu vergleichen, mit Ihren Werten für a und b: Sie können sehen, dass die Unterschiede nicht wirklich signifikant

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' würde eine andere Transponierung benötigen, um die gewünschte Ausgabe zu bekommen, richtig? – Divakar

+0

@Divakar Ja, ja, ich schlage keine Lösung vor, ich sage ausdrücklich, dass Sie Ihre verwenden sollen. Da Ihre Lösung ein Kommentar war, fügte ich den Grund hinzu, warum die Übertragung nicht funktionierte. Wenn Sie eine Antwort geschrieben hätten, hätte ich sie kommentiert. –

+0

Ich habe für den Zweck der Vollständigkeit dieses Beitrags angegeben, wie man zur gewünschten Ausgabe und Form kommt :) – Divakar