2017-01-18 5 views
2

Betrachten Sie diesen Datenrahmen:Pandas Aggregation - Berechnungen zwischen den Spalten

np.random.seed(0) 
df_agg = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar', 
           'foo', 'bar', 'foo', 'foo'], 
         'C' : np.random.choice(2, 8)}) 

Ich mag folgende Spalten von A gruppierten berechnen:

  • Anzahl der Elemente
  • Anzahl von True in C
  • Prozentsatz von True in C
  • Anzahl der False in C
  • Prozentsatz falsch in C

ersten drei Elemente sind einfach mit Aggregationen:

aggregations = { 
    'C': { 
     'Number of elements': 'count', 
     'Number of True':sum, 
     'Percentage of True': 'mean' 
    } 
} 
df_tab = df_agg.groupby('A').agg(aggregations) 
print df_tab 

Und er Ausgang:

     C         
    Number of elements Number of True Percentage of True 
A              
bar     3    2   0.666667 
foo     5    4   0.800000 

Allerdings weiß ich nicht, Wie, in derselben Aggregation, berechnen Sie Spalten, die Kombination von anderen Spalten sind - Anzahl und Prozentsatz von Fals e.

Als Abhilfe kann, kann ich dies tun:

df_tab = df_tab['C'] #flatten 
df_tab['Number of False'] = df_tab['Number of elements'] - df_tab['Number of True'] 
df_tab['Percentage of False'] = 1 - df_tab['Percentage of True'] 

Welche nachgeben, was ich will, aber ich frage mich, wie es auf einmal zu tun.

 Number of elements Number of True Percentage of True Number of False Percentage of False 
A                         
bar     3    2   0.666667    1    0.333333 
foo     5    4   0.800000    1    0.200000 
+0

Ich denke, Ihre Auswahlmöglichkeiten sind 1) definieren sekundäre Spalten wie "Anzahl der falschen" explizit und 2) erstellen Sie einen sekundären Datenrahmen und fügen Sie das an "df_tab". – periphreal

Antwort

1

die folgenden quesiton Beantwortung von that comment:

Ich brauche komplexere Berechnungen Unter der Annahme, und auf andere Spalten beziehen. Gibt es eine Möglichkeit, wie in, auf eine Spalte verweisen beispielsweise Lambda Funktion

Angenommen, wir haben haben folgende DF:

In [62]: %paste 
df = pd.DataFrame(
{'A': {0: 'foo', 
    1: 'bar', 
    2: 'foo', 
    3: 'bar', 
    4: 'foo', 
    5: 'bar', 
    6: 'foo', 
    7: 'foo'}, 
'C': {0: 0, 1: 1, 2: 1, 3: 0, 4: 1, 5: 1, 6: 1, 7: 1}, 
'X': {0: 0.56804456109393231, 
    1: 0.92559663829266103, 
    2: 0.071036058197886942, 
    3: 0.087129299701540708, 
    4: 0.020218397440325719, 
    5: 0.832619845547938, 
    6: 0.77815675094985048, 
    7: 0.87001214824681916}}) 
## -- End pasted text -- 

In [63]: df 
Out[63]: 
    A C   X 
0 foo 0 0.568045 
1 bar 1 0.925597 
2 foo 1 0.071036 
3 bar 0 0.087129 
4 foo 1 0.020218 
5 bar 1 0.832620 
6 foo 1 0.778157 
7 foo 1 0.870012 

Lösung:

groupby.GroupBy.apply() gibt Zugriff auf alle Spalten in dem gruppierten Teil von DF:

In [78]: %paste 
def f(grp): 
    return pd.DataFrame({ 
       'Number of elements':len(grp), 
       'Number of True': grp['C'].sum(), 
       'Percentage of True': grp['C'].mean(), 
       'XXX': grp['C'].mean()/grp['X'].sum()}, # <--- here we access different columns... 
       index=[grp.name]) 
## -- End pasted text -- 

In [79]: df.groupby('A', as_index=False).apply(f) 
Out[79]: 
     Number of True Number of elements Percentage of True  XXX 
0 bar    2     3   0.666667 0.361269 
1 foo    4     5   0.800000 0.346700 
3

können Sie Lambda-Funktionen zur Verfügung:

In [43]: aggregations = { 
    ...:  'C': { 
    ...:   'Number of elements': 'count', 
    ...:   'Number of True':sum, 
    ...:   'Percentage of True': 'mean', 
    ...:   'Number of False': lambda x: len(x) - np.count_nonzero(x), 
    ...:   'Percentage of False': lambda x: 1 - x.mean() 
    ...:  } 
    ...: } 
    ...: 
    ...: df_agg.groupby('A').agg(aggregations) 
    ...: 
Out[43]: 
        C 
    Number of False Percentage of False Number of True Number of elements Percentage of True 
A 
bar    1   0.333333    2     3   0.666667 
foo    1   0.200000    4     5   0.800000 
+0

Ich mag das, gute Idee. In diesem speziellen Fall wird es funktionieren. Aber vorausgesetzt, ich brauche komplexere Berechnungen und verweise auf andere Spalten. Gibt es eine Möglichkeit, auf eine Spalte beispielsweise in der Lambda-Funktion zu verweisen? – HonzaB

+0

@HonzaB, es wird knifflig, da AFAIK '.agg()' separat auf einzelne Spalten angewendet wird – MaxU

+0

@HonzaB, können Sie ein Beispiel machen, wo Sie auf andere Spalten zugreifen müssten? – MaxU

Verwandte Themen