2013-09-03 34 views
6

Diciamo che ho il seguente array:parti somma di numpy.array

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

voglio sommare i primi due valori della prima fila: 1+2 = 3, poi prossimi due valori: 3+4 = 7, e poi 5+6 = 11, e così via per ogni riga. La mia uscita desiderata è questo:

array([[ 3, 7, 11], 
     [15, 19, 23], 
     [ 8, 13, 17]]) 

Ho la seguente soluzione:

def sum_chunks(x, chunk_size): 
    rows, cols = x.shape 
    x = x.reshape(x.size/chunk_size, chunk_size) 
    return x.sum(axis=1).reshape(rows, cols/chunk_size) 

ma ci si sente inutilmente complicato, c'è un modo migliore? Forse un built-in?

risposta

5

Quando devo fare questo genere di cose, preferisco rimodellare l'array 2D in un array 3D, quindi comprimere la dimensione extra con np.sum. Generalizzando ad array n-dimensionale, si potrebbe fare qualcosa di simile:

def sum_chunk(x, chunk_size, axis=-1): 
    shape = x.shape 
    if axis < 0: 
     axis += x.ndim 
    shape = shape[:axis] + (-1, chunk_size) + shape[axis+1:] 
    x = x.reshape(shape) 
    return x.sum(axis=axis+1) 

>>> a = np.arange(24).reshape(4, 6) 
>>> a 
array([[ 0, 1, 2, 3, 4, 5], 
     [ 6, 7, 8, 9, 10, 11], 
     [12, 13, 14, 15, 16, 17], 
     [18, 19, 20, 21, 22, 23]]) 
>>> sum_chunk(a, 2) 
array([[ 1, 5, 9], 
     [13, 17, 21], 
     [25, 29, 33], 
     [37, 41, 45]]) 
>>> sum_chunk(a, 2, axis=0) 
array([[ 6, 8, 10, 12, 14, 16], 
     [30, 32, 34, 36, 38, 40]]) 
1

Ecco un modo:

>>> a[:,::2] + a[:,1::2] 
array([[ 3, 7, 11], 
     [15, 19, 23], 
     [ 8, 13, 17]]) 
5

Basta usare affettare:

a[:,::2] + a[:,1::2] 

Questo prende la matrice formata da ogni colonna anche indicizzati (::2), e lo aggiunge alla matrice formata da ogni colonna indicizzata dispari (1::2).

+0

Grazie, affettare lavora bello per caso "2", ma sarebbe ancora essere bello per una soluzione generale? – Akavall

+0

Come si generalizza questo? Puoi fare 'np.sum ([a [:, i :: n] per i in xrange (n)], 0)' se potresti dover sommare 'n' colonne consecutive, per esempio. – nneonneo

+0

La tua soluzione è più breve e più facile da leggere, ma l'ho programmata e le mie soluzioni iniziali sono notevolmente più veloci. – Akavall