tutorial functions documentacion python pandas pandas-groupby

functions - python pandas download windows



¿Cómo creo una nueva columna a partir de la salida de pandas groupby(). Sum()? (2)

¿Cómo creo una nueva columna con Groupby (). Sum ()?

Hay dos formas: una sencilla y la otra un poco más interesante.

Favorito de todos: GroupBy.transform() con ''sum''

La respuesta de @Ed Chum se puede simplificar, un poco. Llame a DataFrame.groupby lugar de Series.groupby . Esto da como resultado una sintaxis más simple.

# The setup. df[[''Date'', ''Data3'']] Date Data3 0 2015-05-08 5 1 2015-05-07 8 2 2015-05-06 6 3 2015-05-05 1 4 2015-05-08 50 5 2015-05-07 100 6 2015-05-06 60 7 2015-05-05 120

df.groupby(''Date'')[''Data3''].transform(''sum'') 0 55 1 108 2 66 3 121 4 55 5 108 6 66 7 121 Name: Data3, dtype: int64

Es un poco más rápido

df2 = pd.concat([df] * 12345) %timeit df2[''Data3''].groupby(df[''Date'']).transform(''sum'') %timeit df2.groupby(''Date'')[''Data3''].transform(''sum'') 10.4 ms ± 367 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 8.58 ms ± 559 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

No convencional, pero vale la pena considerarlo: GroupBy.sum() + Series.map()

Me topé con una idiosincrasia interesante en la API. Por lo que digo, puede reproducir esto en cualquier versión principal de más de 0.20 (probé esto en 0.23 y 0.24). Parece que siempre puede ahorrar unos pocos milisegundos del tiempo que tarda la transform si en su lugar usa una función directa de GroupBy y la difunde usando el map :

df.Date.map(df.groupby(''Date'')[''Data3''].sum()) 0 55 1 108 2 66 3 121 4 55 5 108 6 66 7 121 Name: Date, dtype: int64

Comparar con

df.groupby(''Date'')[''Data3''].transform(''sum'') 0 55 1 108 2 66 3 121 4 55 5 108 6 66 7 121 Name: Data3, dtype: int64

Mis pruebas muestran que el map es un poco más rápido si puede permitirse usar la función directa GroupBy (como mean , min , max , first , etc.). Es más o menos más rápido para la mayoría de las situaciones generales hasta alrededor de ~ 200 mil registros. Después de eso, el rendimiento realmente depende de los datos.

(Izquierda: v0.23, Derecha: v0.24)

Una buena alternativa para saber, y mejor si tiene marcos más pequeños con un número menor de grupos. . . pero recomendaría transform como primera opción. Pensé que valía la pena compartir esto de todos modos.

Código de referencia, para referencia:

import perfplot perfplot.show( setup=lambda n: pd.DataFrame({''A'': np.random.choice(n//10, n), ''B'': np.ones(n)}), kernels=[ lambda df: df.groupby(''A'')[''B''].transform(''sum''), lambda df: df.A.map(df.groupby(''A'')[''B''].sum()), ], labels=[''GroupBy.transform'', ''GroupBy.sum + map''], n_range=[2**k for k in range(5, 20)], xlabel=''N'', logy=True, logx=True )

Intentando crear una nueva columna a partir del cálculo groupby . En el código a continuación, obtengo los valores calculados correctos para cada fecha (ver el grupo a continuación) pero cuando intento crear una nueva columna ( df[''Data4''] ) consigo NaN. Así que estoy tratando de crear una nueva columna en el marco de datos con la suma de Data3 para todas las fechas y aplicarla a cada fila de fecha. Por ejemplo, 2015-05-08 está en 2 filas (el total es 50 + 5 = 55) y en esta nueva columna me gustaría tener 55 en ambas filas.

import pandas as pd import numpy as np from pandas import DataFrame df = pd.DataFrame({''Date'': [''2015-05-08'', ''2015-05-07'', ''2015-05-06'', ''2015-05-05'', ''2015-05-08'', ''2015-05-07'', ''2015-05-06'', ''2015-05-05''], ''Sym'': [''aapl'', ''aapl'', ''aapl'', ''aapl'', ''aaww'', ''aaww'', ''aaww'', ''aaww''], ''Data2'': [11, 8, 10, 15, 110, 60, 100, 40],''Data3'': [5, 8, 6, 1, 50, 100, 60, 120]}) group = df[''Data3''].groupby(df[''Date'']).sum() df[''Data4''] = group


Desea usar transform this devolverá una serie con el índice alineado al df para que luego pueda agregarlo como una nueva columna:

In [74]: df = pd.DataFrame({''Date'': [''2015-05-08'', ''2015-05-07'', ''2015-05-06'', ''2015-05-05'', ''2015-05-08'', ''2015-05-07'', ''2015-05-06'', ''2015-05-05''], ''Sym'': [''aapl'', ''aapl'', ''aapl'', ''aapl'', ''aaww'', ''aaww'', ''aaww'', ''aaww''], ''Data2'': [11, 8, 10, 15, 110, 60, 100, 40],''Data3'': [5, 8, 6, 1, 50, 100, 60, 120]}) ​ df[''Data4''] = df[''Data3''].groupby(df[''Date'']).transform(''sum'') df Out[74]: Data2 Data3 Date Sym Data4 0 11 5 2015-05-08 aapl 55 1 8 8 2015-05-07 aapl 108 2 10 6 2015-05-06 aapl 66 3 15 1 2015-05-05 aapl 121 4 110 50 2015-05-08 aaww 55 5 60 100 2015-05-07 aaww 108 6 100 60 2015-05-06 aaww 66 7 40 120 2015-05-05 aaww 121