Equivalente de 'recuento (distinto)' de pandas

Resuelto Adriano Almeida asked hace 11 años • 11 respuestas

Estoy usando Pandas como sustituto de la base de datos porque tengo varias bases de datos ( Oracle , SQL Server , etc.) y no puedo realizar una secuencia de comandos en un equivalente de SQL.

Tengo una tabla cargada en un DataFrame con algunas columnas:

YEARMONTH, CLIENTCODE, SIZE, etc., etc.

En SQL, para contar la cantidad de clientes diferentes por año sería:

SELECT count(distinct CLIENTCODE) FROM table GROUP BY YEARMONTH;

Y el resultado sería

201301    5000
201302    13245

¿Cómo puedo hacer eso en Pandas?

Adriano Almeida avatar Mar 14 '13 20:03 Adriano Almeida
Aceptado

Creo que esto es lo que quieres:

table.groupby('YEARMONTH').CLIENTCODE.nunique()

Ejemplo:

In [2]: table
Out[2]: 
   CLIENTCODE  YEARMONTH
0           1     201301
1           1     201301
2           2     201301
3           1     201302
4           2     201302
5           2     201302
6           3     201302

In [3]: table.groupby('YEARMONTH').CLIENTCODE.nunique()
Out[3]: 
YEARMONTH
201301       2
201302       3
Dan Allan avatar Mar 14 '2013 14:03 Dan Allan

Aquí tienes otro método y es mucho más sencillo. Digamos que el nombre de su marco de datos es daaty el nombre de la columna es YEARMONTH:

daat.YEARMONTH.value_counts()
StatguyUser avatar Jul 02 '2017 11:07 StatguyUser

Curiosamente, muy a menudo len(unique())es unas cuantas veces (3x-15x) más rápido que nunique().

Roman Kh avatar May 05 '2014 02:05 Roman Kh

También lo estoy usando nunique, pero será muy útil si tienes que usar una función agregada como 'min', 'max', 'count' or 'mean'etc.

df.groupby('YEARMONTH')['CLIENTCODE'].transform('nunique') #count(distinct)
df.groupby('YEARMONTH')['CLIENTCODE'].transform('min')     #min
df.groupby('YEARMONTH')['CLIENTCODE'].transform('max')     #max
df.groupby('YEARMONTH')['CLIENTCODE'].transform('mean')    #average
df.groupby('YEARMONTH')['CLIENTCODE'].transform('count')   #count
Gangaraju avatar Aug 01 '2019 09:08 Gangaraju

Distinción de columna junto con agregaciones en otras columnas

Para obtener el número distinto de valores para cualquier columna ( CLIENTCODEen su caso), podemos usar nunique. Podemos pasar la entrada como un diccionario en aggfunción, junto con agregaciones en otras columnas:

grp_df = df.groupby('YEARMONTH').agg({'CLIENTCODE': ['nunique'],
                                      'other_col_1': ['sum', 'count']})

# to flatten the multi-level columns
grp_df.columns = ["_".join(col).strip() for col in grp_df.columns.values]

# if you wish to reset the index
grp_df.reset_index(inplace=True)
Vivek Payasi avatar Apr 20 '2020 10:04 Vivek Payasi