Pandas聚合 - 列之间的计算

时间:2017-01-18 13:21:33

标签: python pandas

考虑这个数据框:

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

我想计算按A分组的以下列:

  • 元素数量
  • C
  • 中的真实数量
  • C
  • 中的True百分比
  • C
  • 中的假数
  • C
  • 中的错误百分比

前三个元素使用聚合很简单:

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

他输出:

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

但是我不知道在同一个聚合中如何计算其他列组合的列 - 数量和False的百分比。

作为一种解决方法,我可以这样做:

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

哪个会产生我想要的东西,但我想知道如何一次完成所有这些。

     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

2 个答案:

答案 0 :(得分:3)

你可以使用lambda函数:

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

答案 1 :(得分:1)

that comment回答以下问题:

  

假设我需要更复杂的计算并参考其他列。   有没有办法如何引用一个列,例如lambda   功能

假设我们有以下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

<强>解决方案:

groupby.GroupBy.apply()使我们可以访问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