2010-01-20 13 views
9

Diciamo che hanno una matrice 2D Numpy:array con diverso numero di dimensioni

>>> a = np.random.random((4,6)) 

e voglio aggiungere una matrice 1D per ogni riga:

>>> c = np.random.random((6,)) 
>>> a + c 

Questo funziona. Ora, se provo l'aggiunta di una serie 1D per ogni colonna, ottengo un errore:

>>> b = np.random.random((4,)) 
>>> a + b 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: shape mismatch: objects cannot be broadcast to a single shape 

posso risolvere questo problema utilizzando np.newaxis:

>>> a + b[:,np.newaxis] 

che funziona come previsto.

Quali sono le regole di corrispondenza delle forme per evitare di dover utilizzare np.newaxis? È che l'ultimo elemento della tupla di forma numpy deve corrispondere? Questa regola si applica anche alle dimensioni superiori? Ad esempio, le seguenti opere:

>>> a = np.random.random((2,3,4,5)) 
>>> b = np.random.random((4,5)) 
>>> a + b 

Quindi la mia domanda è se questo è documentato da nessuna parte, e se si tratta di un comportamento che può essere invocato, o se è meglio usare sempre np.newaxis?

risposta

10

Questa è una caratteristica distintiva di numpy denominata broadcasting. Viene fatto usando quattro regole che sono un po 'complicato nella formulazione, ma sono piuttosto intuitivo comprese subito:

  1. All input arrays with ndim smaller than the input array of largest ndim , have 1’s prepended to their shapes.
  2. The size in each dimension of the output shape is the maximum of all the input sizes in that dimension.
  3. An input can be used in the calculation if its size in a particular dimension either matches the output size in that dimension, or has value exactly 1.
  4. If an input has a dimension size of 1 in its shape, the first data entry in that dimension will be used for all calculations along that dimension. In other words, the stepping machinery of the ufunc will simply not step along that dimension (the stride will be 0 for that dimension).

L'operazione è possibile (risultato doesnt in shape mismatch errore citato) in tre casi:

  1. The arrays all have exactly the same shape.
  2. The arrays all have the same number of dimensions and the length of each dimensions is either a common length or 1.
  3. The arrays that have too few dimensions can have their shapes prepended with a dimension of length 1 to satisfy property 2.

Gli esempi possono essere trovati tramite il link sopra.

+0

Questo ora ha senso - grazie! – astrofrog

2

Vediamo se ho capito ...

>>> from numpy import ones, newaxis 
>>> A = ones((4,3)) # 4 rows x 3 cols 
>>> A.shape 
(4, 3) 
>>> A 
array([[ 1., 1., 1.], 
     [ 1., 1., 1.], 
     [ 1., 1., 1.], 
     [ 1., 1., 1.]]) 
>>> 
>>> ones((4,1))  # 4 rows x 1 col 
array([[ 1.], 
     [ 1.], 
     [ 1.], 
     [ 1.]]) 
>>> A + ones((4,1)) 
array([[ 2., 2., 2.], 
     [ 2., 2., 2.], 
     [ 2., 2., 2.], 
     [ 2., 2., 2.]]) 
>>> 
>>> ones((1,3))  # 1 row x 3 cols 
array([[ 1., 1., 1.]]) 
>>> A + ones((1,3)) 
array([[ 2., 2., 2.], 
     [ 2., 2., 2.], 
     [ 2., 2., 2.], 
     [ 2., 2., 2.]]) 
>>> 
>>> B = ones((3,)) # a 1D array 
>>> B 
array([ 1., 1., 1.]) 
>>> B.shape 
(3,) 
>>> A + B 
array([[ 2., 2., 2.], 
     [ 2., 2., 2.], 
     [ 2., 2., 2.], 
     [ 2., 2., 2.]]) 
>>> 
>>> C = ones((4,)) # a 1D array 
>>> C.shape 
(4,) 
>>> C 
array([ 1., 1., 1., 1.]) 
>>> A + C 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: shape mismatch: objects cannot be broadcast to a single shape 
>>> 
>>> D = C[:,newaxis] 
>>> D.shape 
(4, 1) 
>>> A + D 
array([[ 2., 2., 2.], 
     [ 2., 2., 2.], 
     [ 2., 2., 2.], 
     [ 2., 2., 2.]]) 

La trasmissione necessaria per fare 4 x 3 vettore oltre a un vettore 1D con 3 elementi riesce.

La trasmissione necessaria per eseguire il vettore 4 x 3 più un vettore 1D con 4 elementi non riesce.

>>> D = C[:,newaxis] 

converte C in un vettore 2D di una forma compatibile.

Problemi correlati