Python numpy o pandas equivalente de la función R de barrido ()

¿Cuál es el equivalente numpy o pandas del sweep() de la función R sweep() ?

Para elaborar: en R digamos que tenemos un vector de coeficiente (por ejemplo, tipo beta – numérico) y una matriz (por ejemplo, datos – tipo numérico 20×5). Quiero superponer el vector en cada fila de la matriz y multiplicar los elementos correspondientes. Y luego devuelva la matriz resultante (20×5) que podría lograr usando sweep() . Encuentra debajo el código R muestra.

 beta <- c(10, 20, 30, 40) data  data [,1] [,2] [,3] [,4] [1,] 1 6 11 16 [2,] 2 7 12 17 [3,] 3 8 13 18 [4,] 4 9 14 19 [5,] 5 10 15 20 > beta [1] 10 20 30 40 > sweep(data,MARGIN=2,beta,`*`) [,1] [,2] [,3] [,4] [1,] 10 120 330 640 [2,] 20 140 360 680 [3,] 30 160 390 720 [4,] 40 180 420 760 [5,] 50 200 450 800 

He escuchado cosas emocionantes sobre los numpy y los pandas en Python y parece que tienen muchos comandos tipo R ¿Cuál sería la forma más rápida de lograr lo mismo utilizando estas bibliotecas? Los datos reales tienen millones de filas y alrededor de 50 columnas. El vector beta es, por supuesto, compatible con los datos.

Las pandas también tienen un método de aplicación, que es lo que utiliza el barrido de R bajo el capó. (Tenga en cuenta que el argumento MARGIN es “equivalente” al argumento del eje en muchas funciones de pandas, excepto que toma los valores 0 y 1 en lugar de 1 y 2 ).

 In [11]: np.random.seed = 1 In [12]: beta = pd.Series(np.random.randn(5)) In [13]: data = pd.DataFrame(np.random.randn(20, 5)) 

Puede utilizar una aplicación con una función que se llama contra cada fila:

 In [14]: data.apply(lambda row: row * beta, axis=1) 

Nota: ese eje = 0 se aplicaría a cada columna, este es el valor predeterminado, ya que los datos se almacenan por columnas y, por lo tanto, las operaciones por columnas son más eficientes.

Sin embargo, en este caso, es fácil hacer que la vectorización sea significativamente más rápida (y más legible), simplemente multiplicando por filas:

 In [21]: data.apply(lambda row: row * beta, axis=1).head() Out[21]: 0 1 2 3 4 0 -0.024827 -1.465294 -0.416155 -0.369182 -0.649587 1 0.026433 0.355915 -0.672302 0.225446 -0.520374 2 0.042254 -1.223200 -0.545957 0.103864 -0.372855 3 0.086367 0.218539 -1.033671 0.218388 -0.598549 4 0.203071 -3.402876 0.192504 -0.147548 -0.726001 In [22]: data.mul(beta, axis=1).head() # just show first few rows with head Out[22]: 0 1 2 3 4 0 -0.024827 -1.465294 -0.416155 -0.369182 -0.649587 1 0.026433 0.355915 -0.672302 0.225446 -0.520374 2 0.042254 -1.223200 -0.545957 0.103864 -0.372855 3 0.086367 0.218539 -1.033671 0.218388 -0.598549 4 0.203071 -3.402876 0.192504 -0.147548 -0.726001 

Nota: esto es un poco más robusto / permite más control que usar * .

Puede hacer lo mismo en números (es decir, data.values aquí), ya sea multiplicando directamente, esto será más rápido ya que no se preocupa por la alineación de los datos, o utilizando vectorizar en lugar de aplicar.

En numpy el concepto se llama “broadcasting”. Ejemplo:

 import numpy as np x = np.random.random((4, 3)) x * np.array(range(4))[:, np.newaxis] # sweep along the rows x + np.array(range(3))[np.newaxis, :] # sweep along the columns 

¿Esto funciona más rápido?

 t(t(data) * beta) 

Algunas otras grandes respuestas aquí con el perfil ¿ Multiplica filas de matrices por vector?

y, finalmente, para responder a su consulta sobre numpy. Use esta referencia (busque la multiplicación de matrices) http://mathesaurus.sourceforge.net/r-numpy.html