2015-09-15 12 views
10

Biorąc pod uwagę Pandas DataFrame, która ma wiele kolumn z wartościami kategorycznymi (0 lub 1), czy można wygodnie uzyskać wartości równe dla każdej kolumny w tym samym czasie?Jak uzyskać wartości liczbowe dla wielu kolumn naraz w Pandas DataFrame?

Na przykład, załóżmy wygenerować DataFrame następująco:

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

mogę uzyskać DataFrame tak:

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 

Jak wygodnie dostać liczniki wartości dla każdej kolumny i uzyskać następujące wygodnie?

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

Moje obecne rozwiązanie jest:

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) 

Ale musi być prostszy sposób, jak układanie, odchylając lub GroupBy?

+0

[Ta odpowiedź poniżej] (https://stackoverflow.com/a/47187144/3707607) zapewnia inny sposób z 'pd.crosstab'. Ponadto, 'value_counts' jest funkcją najwyższego poziomu, a obecnie wybraną odpowiedź można uprościć do' df.apply (pd.value_counts) ' –

Odpowiedz

22

Wystarczy zadzwonić apply i przekazać 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

Jak mogę o tym nie myśleć? Znakomity! – Xin

+0

Jeśli zmienne nie znajdują się w tym samym zakresie, nieistniejące wartości są wyświetlane jako wartości NaN (oczywiście). uważaj na ludzi! – VishnuVardhanA

+0

Czy istnieje sposób użycia tego dla niektórych wybranych kolumn? – deadcode

3

Tu jest rzeczywiście dość ciekawy i zaawansowany sposób robienia tego problemu z crosstab i 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 

Możemy najpierw stopić 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 

Następnie użyj funkcji tabeli krzyżowej, aby policzyć wartości dla każdej kolumny. Ten zachowuje typ danych jako wskazówki, które nie byłyby w przypadku aktualnie wybranej odpowiedzi:

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 

lub w jednej linii, która rozszerza nazw kolumn do nazw parametrów z ** (jest to zaawansowany)

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

Ponadto, value_counts jest teraz funkcją najwyższego poziomu. Więc można uprościć aktualnie wybraną odpowiedź na następujące kwestie:

df.apply(pd.value_counts) 
Powiązane problemy