简体   繁体   English

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

[英]Pandas: Transpose, groupby and summarize columns

i have a pandas DataFrame which looks like this: 我有一个像这样的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        |

I need to transpose this table, add "Name" column with the name of the filter and summarize Filters column values. 我需要转置此表,添加带有过滤器名称的“名称”列,并汇总过滤器列值。 The result table should be like this: 结果表应该是这样的:

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

The only solution i have came so far was to use apply function on groupped by Id column, but this mehod is too slow for my case - dataset can be more than 40 columns and 50_000 rows, how can i do this with pandas native methods?(eg Pivot, Transpose, Groupby) 我到目前为止唯一的解决方案是使用由Id列分组的应用函数,但这个方法对我的情况来说太慢了 - 数据集可以超过40列和50_000行,我怎么能用pandas本机方法做到这一点? (例如Pivot,Transpose,Groupby)

Use: 采用:

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

stack then groupby 然后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

Short version 简洁版本

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

Using filter and melt 使用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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM