2015-09-15 15 views
10

Dato un DataFrame di Pandas che ha più colonne con valori categoriali (0 o 1), è possibile ottenere convenientemente i valori_conti per ogni colonna allo stesso tempo?Come ottenere il conteggio dei valori per più colonne contemporaneamente in Pandas DataFrame?

Per esempio, supponiamo che io generare un dataframe come segue:

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')) 

posso ottenere un dataframe come questo:

a b c d 
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 

Come posso comodamente ottenere i conteggi di valore per ogni colonna e di ottenere il seguente convenientemente?

a b c d 
0 6 3 2 6 
1 4 7 8 4 

mia soluzione attuale è:

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) 

Ma ci deve essere un modo più semplice, come impilare, facendo perno, o GroupBy?

+0

[Questa risposta qui sotto] (https://stackoverflow.com/a/47187144/3707607) fornisce un approccio diverso con 'pd.crosstab'. Inoltre, 'value_counts' è una funzione di livello superiore e la risposta attualmente selezionata può essere semplificata in' df.apply (pd.value_counts) ' –

risposta

22

Basta chiamare apply e passare 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]: 
    a b c d 
0 4 6 4 3 
1 6 4 6 7 
+1

Come posso non pensarci? Brillante! – Xin

+0

Se le variabili non sono nello stesso intervallo, i valori non esistenti vengono visualizzati come valori NaN (ovviamente). fai attenzione alla gente! – VishnuVardhanA

+0

c'è un modo per usarlo per alcune colonne selezionate? – deadcode

3

V'è in realtà un modo abbastanza interessante e avanzato di fare questo problema con crosstab e melt

df = pd.DataFrame({'a': ['table', 'chair', 'chair', 'lamp', 'bed'], 
        'b': ['lamp', 'candle', 'chair', 'lamp', 'bed'], 
        'c': ['mirror', 'mirror', 'mirror', 'mirror', 'mirror']}) 

df 

     a  b  c 
0 table lamp mirror 
1 chair candle mirror 
2 chair chair mirror 
3 lamp lamp mirror 
4 bed  bed mirror 

Possiamo prima sciogliere il 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 

Quindi utilizzare la funzione tabella a campi incrociati per contare i valori per ogni colonna. Ciò preserva il tipo di dati come interi che non sarebbe il caso per la risposta attualmente selezionato:

pd.crosstab(index=df['index'], columns=df['columns']) 

columns a b c 
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 in una linea, che amplia i nomi delle colonne per i nomi dei parametri con ** (questo è avanzato)

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

Inoltre, value_counts è ora una funzione di livello superiore. Così è possibile semplificare la risposta attualmente selezionato al seguente:

df.apply(pd.value_counts) 
Problemi correlati