¿Cómo obtener recuentos de valores para varias columnas a la vez en Pandas DataFrame?

Dado un Pandas DataFrame que tiene múltiples columnas con valores categóricos (0 o 1), ¿es posible obtener las cuentas_valoradas para cada columna al mismo tiempo?

Por ejemplo, supongamos que genero un DataFrame como sigue:

import numpy as np import pandas as pd np.random.seed(0) df = pd.DataFrame(np.random.randint(0, 2, (10, 4)), columns=list('abcd')) 

Puedo obtener un DataFrame como este:

  abcd 0 0 1 1 0 1 1 1 1 1 2 1 1 1 0 3 0 1 0 0 4 0 0 0 1 5 0 1 1 0 6 0 1 1 1 7 1 0 1 0 8 1 0 1 1 9 0 1 1 0 

¿Cómo obtengo convenientemente los recuentos de valores para cada columna y obtengo lo siguiente de manera conveniente?

  abcd 0 6 3 2 6 1 4 7 8 4 

Mi solución actual es:

 pieces = [] for col in df.columns: tmp_series = df[col].value_counts() tmp_series.name = col pieces.append(tmp_series) df_value_counts = pd.concat(pieces, axis=1) 

¿Pero debe haber una forma más simple, como astackr, pivotar o agrupar?

Simplemente llame a apply y pase pd.Series.value_counts :

 In [212]: df = pd.DataFrame(np.random.randint(0, 2, (10, 4)), columns=list('abcd')) df.apply(pd.Series.value_counts) Out[212]: abcd 0 4 6 4 3 1 6 4 6 7 

En realidad, existe una forma bastante interesante y avanzada de resolver este problema con la crosstab y la melt

 df = pd.DataFrame({'a': ['table', 'chair', 'chair', 'lamp', 'bed'], 'b': ['lamp', 'candle', 'chair', 'lamp', 'bed'], 'c': ['mirror', 'mirror', 'mirror', 'mirror', 'mirror']}) df abc 0 table lamp mirror 1 chair candle mirror 2 chair chair mirror 3 lamp lamp mirror 4 bed bed mirror 

Primero podemos fundir el DataFrame

 df1 = df.melt() df1 columns index 0 a table 1 a chair 2 a chair 3 a lamp 4 a bed 5 b lamp 6 b candle 7 b chair 8 b lamp 9 b bed 10 c mirror 11 c mirror 12 c mirror 13 c mirror 14 c mirror 

Y luego use la función de tabla de referencias cruzadas para contar los valores de cada columna. Esto conserva el tipo de datos como puntos que no serían el caso para la respuesta seleccionada actualmente:

 pd.crosstab(index=df['index'], columns=df['columns']) columns abc index bed 1 1 0 candle 0 1 0 chair 2 1 0 lamp 1 2 0 mirror 0 0 5 table 1 0 0 

O en una línea, que expande los nombres de columna a nombres de parámetros con ** (esto es avanzado)

 pd.crosstab(**df.melt(var_name='columns', value_name='index')) 

Además, value_counts es ahora una función de nivel superior. Así que puedes simplificar la respuesta actualmente seleccionada a lo siguiente:

 df.apply(pd.value_counts)