熊猫:转置,分组和汇总列

时间:2019-05-12 16:34:03

标签: python pandas dataframe

我有一个看起来像这样的pandas DataFrame:

| Id | Filter 1 | Filter 2 | Filter 3 |
|----|----------|----------|----------|
| 25 | 0        | 1        | 1        |
| 25 | 1        | 0        | 1        |
| 25 | 0        | 0        | 1        |
| 30 | 1        | 0        | 1        |
| 31 | 1        | 0        | 1        |
| 31 | 0        | 1        | 0        |
| 31 | 0        | 0        | 1        |

我需要转置该表,在“名称”列中添加过滤器的名称并汇总“过滤器”列的值。结果表应如下所示:

| Id | Name     | Summ |
| 25 | Filter 1 | 1    |
| 25 | Filter 2 | 1    |
| 25 | Filter 3 | 3    |
| 30 | Filter 1 | 1    |
| 30 | Filter 2 | 0    |
| 30 | Filter 3 | 1    |
| 31 | Filter 1 | 1    |
| 31 | Filter 2 | 1    |
| 31 | Filter 3 | 2    |

到目前为止,我唯一的解决方案是对ID列分组使用apply函数,但是这种方法对于我的情况来说太慢了-数据集可能超过40列和50_000行,我该如何使用pandas做到这一点本机方法?(例如,Pivot,Transpose,Groupby)

3 个答案:

答案 0 :(得分:2)

使用:

df_new=df.melt('Id',var_name='Name',value_name='Sum').groupby(['Id','Name']).Sum.sum()\
                                                                 .reset_index()
print(df_new)

   Id      Name  Sum
0  25  Filter 1    1
1  25  Filter 2    1
2  25  Filter 3    3
3  30  Filter 1    1
4  30  Filter 2    0
5  30  Filter 3    1
6  31  Filter 1    1
7  31  Filter 2    1
8  31  Filter 3    1

答案 1 :(得分:1)

stack然后groupby

df.set_index('Id').stack().groupby(level=[0,1]).sum().reset_index()
   Id   level_1  0
0  25  Filter 1  1
1  25  Filter 2  1
2  25  Filter 3  3
3  30  Filter 1  1
4  30  Filter 2  0
5  30  Filter 3  1
6  31  Filter 1  1
7  31  Filter 2  1
8  31  Filter 3  1

简短版本

df.set_index('Id').sum(level=0).stack()#df.groupby('Id').sum().stack()

答案 2 :(得分:0)

使用filtermelt

df.filter(like='Filter').groupby(df.Id).sum().T.reset_index().melt(id_vars='index')

    index       Id  value
0   Filter 1    25  1
1   Filter 2    25  1
2   Filter 3    25  3
3   Filter 1    30  1
4   Filter 2    30  0
5   Filter 3    30  1
6   Filter 1    31  1
7   Filter 2    31  1
8   Filter 3    31  2