2017-09-01 1 views
2

Ich versuche etwas zu tun, von dem ich weiß, dass es einfache Pandas sein muss, aber ich zerreiße mein Gehirn, um es herauszufinden. Ich möchte Proportionen und zählt jeder Gruppe für eine beliebige Ebene der Gruppe-bys verfügbar sein:pandas groupby count und proportion

import pandas as pd 

df = pd.DataFrame({'A': [1, 0, 1, 0, 1, 0, 0, 0], 'B': ['A'] * 4 + ['B'] * 4}) 

gb = df.groupby(['A', 'B']).size() 

prop_gb = gb/gb.groupby(level=0).sum() 

prop_gb ist jetzt:

prop_gb 
Out[116]: 
A B 
0 A 0.400000 
    B 0.600000 
1 A 0.666667 
    B 0.333333 
dtype: float64 

ich schließlich wollen dies, obwohl:

A B  prop count 
0 A 0.400000  2 
    B 0.600000  3 
1 A 0.666667  2 
    B 0.333333  1 

Ich habe versucht, die beiden pandas.Series Objekte, gb und prop_gb durch die Umwandlung in Wörterbücher und "Beitritt" sie auf diese Weise, aber ich weiß, es muss ein nativer Pandas Weg, dies zu erreichen ...

Das technisch was erreicht Ich möchte:

desired = {k: (v, prop_gb.to_dict()[k]) for k, v in gb.to_dict().items()} 
desired 
{(0, 'A'): (2, 0.40000000000000002), 
(0, 'B'): (3, 0.59999999999999998), 
(1, 'A'): (2, 0.66666666666666663), 
(1, 'B'): (1, 0.33333333333333331)} 

Antwort

1

Sie nur to_frame verwenden könnte einen Datenrahmen zu schaffen, mit zu beginnen, und fügen Sie die prop Spalte:

>>> desired = df.groupby(['A', 'B']).size().to_frame('count') 
>>> desired['prop'] = gb/gb.groupby(level=0).sum() 
>>> desired 
    count  prop 
A B     
0 A  2 0.400000 
    B  3 0.600000 
1 A  2 0.666667 
    B  1 0.333333 

Alternative, einen neuen Rahmen aus der 2-Serie erstellen:

>>> pd.DataFrame(dict(prop=prop_gb, count=gb)) 
    count  prop 
A B     
0 A  2 0.400000 
    B  3 0.600000 
1 A  2 0.666667 
    B  1 0.333333 
1

Concat die beiden Reihen Sie erstellt haben:

df = pd.concat([prop_gb, gb], axis=1) 
df.columns = ['prop', 'count'] 

df 

     prop count 
A B 
0 A 0.400000 2 
    B 0.600000 3 
1 A 0.666667 2 
    B 0.333333 1 
1

Sie können diese Werte in einem Ausdruck produzieren etwa so:

df.groupby(['A', 'B']).size().agg(
    {'count': lambda x: x, 'prop':lambda x: x/x.sum(level=0)} 
).unstack(level=0).reset_index() 
# A B count  prop 
# 0 0 A 2.0 0.400000 
# 1 0 B 3.0 0.600000 
# 2 1 A 2.0 0.666667 
# 3 1 B 1.0 0.333333