He revisado varias publicaciones aquí sobre mejores formas de recorrer los marcos de datos, pero parece que no puedo averiguar cómo aplicarlas a mi situación específica.

Tengo un marco de datos de aproximadamente 2 millones de filas y necesito calcular seis estadísticas para cada fila, una por columna. Hay 3 columnas, por lo que 18 en total. Sin embargo, el problema es que necesito actualizar esas estadísticas usando una muestra del marco de datos para que la media / mediana, etc., sea diferente por fila.

Esto es lo que tengo hasta ahora:

r = 0
for i in imputed_df.iterrows():
    t = imputed_df.sample(n=10)
    for (columnName) in cols:
        imputed_df.loc[r,columnName + '_mean'] = t[columnName].mean()
        imputed_df.loc[r,columnName + '_var'] = t[columnName].var()
        imputed_df.loc[r,columnName + '_std'] = t[columnName].std()
        imputed_df.loc[r,columnName + '_skew'] = t[columnName].skew()
        imputed_df.loc[r,columnName + '_kurt'] = t[columnName].kurt()
        imputed_df.loc[r,columnName + '_med'] = t[columnName].median()

Pero esto lleva funcionando dos días sin terminar. Intenté tomar un subconjunto de 2000 filas del marco de datos original e incluso ese se ha estado ejecutando durante horas.

¿Hay una mejor manera de hacer esto?

EDITAR: Se agregó un conjunto de datos de muestra de cómo debería verse. cada columna con sufijo debe tener el valor calculado del subconjunto de 10 filas.

    timestamp   activityID  w2  w3  w4
0   41.21   1.0     -1.34587    9.57245     2.83571
1   41.22   1.0     -1.76211    10.63590    2.59496
2   41.23   1.0     -2.45116    11.09340    2.23671
3   41.24   1.0     -2.42381    11.88590    1.77260
4   41.25   1.0     -2.31581    12.45170    1.50289
0
Seve Martinez 27 oct. 2020 a las 22:35

1 respuesta

La mejor respuesta

El problema es que realiza la operación para cada columna utilizando bucles innecesarios. Podríamos usar DataFrame.agg con DataFrame.unstack y Series.set_axis para obtener los nombres correctos de las columnas.

Configuración

import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randint(0, 10, (10, 100))).add_prefix('col')

new_serie = df.agg(['sum', 'mean', 
                    'var', 'std', 
                    'skew', 'kurt', 'median']).unstack()
new_df = pd.concat([df, new_serie.set_axis([f'{x}_{y}'
                                            for x, y in new_serie.index])
                                  .to_frame().T], axis=1)

# if new_df already exist:
#new_df.loc[0, :] = new_serie.set_axis([f'{x}_{y}' for x, y in new_serie.index])

   col0  col1  col2  col3  col4  col5  col6  col7  col8  col9  ...  \
0     8     7     6     7     6     5     8     7     8     4  ...   
1     8     1     8     7     0     8     8     4     6     1  ...   
2     5     6     3     5     4     9     3     0     2     5  ...   
3     3     3     3     3     5     4     5     1     3     5  ...   
4     7     9     4     5     6     7     0     3     4     6  ...   
5     0     5     2     0     8     0     3     7     6     5  ...   
6     7     0     1     4     8     9     4     9     2     9  ...   
7     0     6     1     0     6     1     3     0     3     4  ...   
8     3     6     1     8     3     0     7     6     8     6  ...   
9     2     5     8     5     8     4     9     1     9     9  ...   

   col98_skew  col98_kurt  col98_median  col99_sum  col99_mean  col99_var  \
0    0.456435   -0.939607           3.0       39.0         3.9   6.322222   
1         NaN         NaN           NaN        NaN         NaN        NaN   
2         NaN         NaN           NaN        NaN         NaN        NaN   
3         NaN         NaN           NaN        NaN         NaN        NaN   
4         NaN         NaN           NaN        NaN         NaN        NaN   
5         NaN         NaN           NaN        NaN         NaN        NaN   
6         NaN         NaN           NaN        NaN         NaN        NaN   
7         NaN         NaN           NaN        NaN         NaN        NaN   
8         NaN         NaN           NaN        NaN         NaN        NaN   
9         NaN         NaN           NaN        NaN         NaN        NaN   

   col99_std  col99_skew  col99_kurt  col99_median  
0   2.514403    0.402601    1.099343           4.0  
1        NaN         NaN         NaN           NaN  
2        NaN         NaN         NaN           NaN  
3        NaN         NaN         NaN           NaN  
4        NaN         NaN         NaN           NaN  
5        NaN         NaN         NaN           NaN  
6        NaN         NaN         NaN           NaN  
7        NaN         NaN         NaN           NaN  
8        NaN         NaN         NaN           NaN  
9        NaN         NaN         NaN           NaN 
1
ansev 27 oct. 2020 a las 19:56