2011-12-28 9 views
7

Estoy confundido acerca de cuándo la función numpy.apply_along_axis() de numpy superará a un simple bucle de Python. Por ejemplo, consideremos el caso de una matriz con muchas filas, y desea calcular la suma de cada fila:¿Por qué numpy.apply_along_axis parece ser más lento que el bucle de Python?

x = np.ones([100000, 3]) 
sums1 = np.array([np.sum(x[i,:]) for i in range(x.shape[0])]) 
sums2 = np.apply_along_axis(np.sum, 1, x) 

Aquí aún estoy usando una función integrada de numpy, np.sum, y sin embargo el cálculo sums1 (Ciclo de Python) toma menos de 400 ms mientras calcula sums2 (apply_along_axis) toma más de 2000ms (NumPy 1.6.1 en Windows). A modo de comparación, la función rowMeans de R a menudo puede hacer esto en menos de 20 ms (estoy bastante seguro de que está llamando al código C) mientras que la función R similar apply() puede hacerlo en aproximadamente 600 ms.

+0

Desafortunadamente aplicar a lo largo del eje parece ser una opción para tareas no relacionadas con la velocidad solamente. – Wizard

Respuesta

10

np.sum tomar un parámetro axis, por lo que podría calcular la suma simple uso de

sums3 = np.sum(x, axis=1) 

Esto es mucho más rápido que los 2 métodos que usted plantea.

$ python -m timeit -n 1 -r 1 -s "import numpy as np;x=np.ones([100000,3])" "np.apply_along_axis(np.sum, 1, x)" 
1 loops, best of 1: 3.21 sec per loop 

$ python -m timeit -n 1 -r 1 -s "import numpy as np;x=np.ones([100000,3])" "np.array([np.sum(x[i,:]) for i in range(x.shape[0])])" 
1 loops, best of 1: 712 msec per loop 

$ python -m timeit -n 1 -r 1 -s "import numpy as np;x=np.ones([100000,3])" "np.sum(x, axis=1)" 
1 loops, best of 1: 1.81 msec per loop 

(En cuanto a por qué es más lento apply_along_axis -. No sé, probablemente debido a que la función está escrito en Python puro y es mucho más genérico y por lo tanto menos oportunidades de optimización que la versión de serie)

Cuestiones relacionadas