Pandas汇总多个列

时间:2017-11-02 04:16:40

标签: python pandas-groupby

我有以下数据框

import pandas as pd
import numpy as np
from IPython.display import display

arrays = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'],
         ['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']]
index = pd.MultiIndex.from_arrays(arrays, names=['first', 'second'])
df = pd.DataFrame({'A': np.arange(8),
                   'B': np.arange(8),
                    'C': np.arange(8)},
                  index=index)
df

enter image description here

我现在想要一个数据帧,其内容是“first”组下所有元素的总和,即

<!DOCTYPE html>
<html>
<head>
<style>
table, th, td {
    border: 1px solid black;
}
</style>
</head>
<body>

<table style="width:100%">
  <tr>
    <th>first</th>
    <th>sum</th>     
  </tr>
  <tr>
    <td>bar</td>
    <td>3</td>    
  </tr>
  <tr>
    <td>baz</td>
    <td>15</td>    
  </tr>
  <tr>
    <td>foo</td>
    <td>27</td>    
  </tr>
  <tr>
    <td>qux</td>
    <td>39</td>    
  </tr>
</table>
</body>
</html>

我尝试过以下代码

grouped = df.groupby([pd.Grouper(level='first')])
grouped.sum(axis='columns')

但是抱怨“f()得到了一个意外的关键字参数'axis'”。有没有办法通过抑制其中一个索引来在多索引数据帧上运行聚合函数?

2 个答案:

答案 0 :(得分:1)

方式1

此代码

grouped = df.reset_index().groupby('first').sum()
sum_by_columns = grouped.sum(axis=1).to_frame()
sum_by_columns.columns = ['sum']
print(sum_by_columns)

将提供您想要的输出

       sum
first     
bar      3
baz     15
foo     27
qux     39

这里的士气是groups.sum()分别适用于每一列。

方式2

您可以使用自己的聚合功能:

sum_by_columns = df.groupby([pd.Grouper(level='first')]).apply(lambda x: x.sum().sum())
sum_by_columns.columns = ['sum']
print(sum_by_columns)

它会引导你得到同样的结果。这里,lambda不是应用于每一列,而是应用于每个部分数据帧。

方式3

如果您需要跨列聚合,可以先使用df.stack()方法将其转换为行:

sum_by_columns = df.stack().groupby(pd.Grouper(level='first')).sum().to_frame()
sum_by_columns.columns = ['sum']
print(sum_by_columns)

答案 1 :(得分:0)

 df.groupby(by="first").sum() will give you, (by="w/e you want them to be group by")
            A   B   C
    first            
    bar     1   1   1
    baz     5   5   5
    foo     9   9   9
    qux    13  13  13

 df.groupby(by="first").sum().sum(axis=1) will give you 
first
bar     3
baz    15
foo    27
qux    39