2012-04-28 102 views
6

tengo una matriz:Obtener sumas de pares de elementos en una matriz numpy

t = [4, 5, 0, 7, 1, 6, 8, 3, 2, 9] 

que es sólo una barajadura al azar de la gama [0, 9]. Necesito calcular este:

t2 = [9, 5, 7, 8, 7, 14, 11, 5, 11, 13] 

que es justo:

t2 = [t[0]+t[1], t[1]+t[2], t[2]+t[3], t[3]+t[4], ..., t[9]+t[0]] 

¿Hay alguna manera de hacer esto con numpy para evitar una pitón de bucle cuando se trata de grandes matrices?

Respuesta

18

Usted podría tomar ventaja de la capacidad de una gama NumPy para resumir elemento a elemento:

In [5]: import numpy as np 

In [6]: t = np.array([4, 5, 0, 7, 1, 6, 8, 3, 2, 9]) 

In [7]: t + np.r_[t[1:],t[0]] 
Out[7]: array([ 9, 5, 7, 8, 7, 14, 11, 5, 11, 13]) 

np.r_ es una manera de concatenar secuencias entre sí para formar una nueva matriz numpy. Como veremos a continuación, resulta que no es la mejor manera en este caso.


Otra posibilidad es:

In [10]: t + np.roll(t,-1) 
Out[10]: array([ 9, 5, 7, 8, 7, 14, 11, 5, 11, 13]) 

Aparece usando np.roll es significativamente más rápido:

In [11]: timeit t + np.roll(t,-1) 
100000 loops, best of 3: 17.2 us per loop 

In [12]: timeit t + np.r_[t[1:],t[0]] 
10000 loops, best of 3: 35.5 us per loop 
+0

Tuve que Google lo que 'np.r_' hace :) ¿Podría agregar el enlace y una breve explicación de la respuesta? – ovgolovin

+0

@ovgolovin: hecho! – unutbu

1

Usted puede hacer esto bastante felizmente con zip(), una lista rebanada, y a list comprehension:

t2 = [a+b for (a, b) in zip(t, t[1:])] 
t2.append(t[0]+t[-1]) 

Necesitamos el extra append() añadir en el último elemento, como zip() sólo funciona hasta que termine el iterador más corto. Una comprensión de lista es significativamente más rápida que un ciclo for normal ya que está implementado en C-lado en Python, en lugar de como un bucle de Python.

La alternativa es utilizar itertools.zip_longest:.

from itertools import zip_longest 
t2 = [a+b for (a, b) in zip_longest(t, t[1:], fillvalue=t[0])] 

para llenar el valor extra en Ten en cuenta que esta función es itertools.izip_longest en Python 2.x

+0

El autor pidió específicamente que resolviera la tarea ** con numpy ** para evitar la sobrecarga del ciclo de Python. – ovgolovin

+3

@ovgolovin No, pidió evitar un bucle python, y una lista de comprensión se realiza como un bucle en C dentro de Python. Esto significa que es significativamente más rápido que un bucle normal. –

+3

Aún será increíblemente subóptimo en comparación con las operaciones de vectores Numpy. –

1

¿Qué hay de

import numpy as np 
t = np.array([4, 5, 0, 7, 1, 6, 8, 3, 2, 9]) 

new_t = t + np.hstack((t[1:], [t[0]])) 

Resultado:

>>> new_t 
array([ 9, 5, 7, 8, 7, 14, 11, 5, 11, 13]) 
+0

+1 para otra solución, aunque es un poco más lenta que la respuesta aceptada. – amillerrhodes

Cuestiones relacionadas