首页 > 解决方案 > Groupby多列并计算Pandas中总和的百分比

问题描述

df给定如下数据集:

  type module   item  value  input
0    A      a  item1      2      1
1    A      a  item2      3      0
2    A     aa  item3      4      1
3    A     aa  item4      3      0
4    A     aa  item5      1     -1
5    B      b  item1      5      0
6    B      b  item2      1     -1
7    B     bb  item3      3      0
8    B     bb  item4      3      1
9    B     bb  item5      4      0

我需要根据以下逻辑进行计算:首先,我们只取sumwho is or作为有效值。然后我需要 groupby来计算总和的百分比,例如,第一行的由 计算,由计算,而不是除以,因为输入值是所以它被排除在外。中的列由 groupby然后 sum of计算。pctvalueinput01type, modulepctA-a-item12/(2 + 3) = 0.4A-aa-item14/(4 + 3) = 0.578A-aa-item3-1sumdf2type modulesum

df1:

  type module   item  value  input       pct 
0    A      a  item1      2      1  0.400000
1    A      a  item2      3      0  0.000000 
2    A     aa  item1      4      1  0.571429 
3    A     aa  item2      3      0  0.000000 
4    A     aa  item3      1     -1  0.000000 
5    B      b  item1      5      0  0.000000 
6    B      b  item2      1     -1  0.000000 
7    B     bb  item1      3      0  0.000000 
8    B     bb  item2      3      1  0.300000 
9    B     bb  item3      4      0  0.000000

df2:

  type module   sum
0    A      a  0.40
1    A     aa  0.57
2    B      b  0.00
3    B     bb  0.30

如何根据给定的数据集获得类似的结果?谢谢。

标签: python-3.xpandasdataframepandas-groupby

解决方案


您可以将不匹配条件替换Series.eq为 for compare by 1with0和 compare by 0, 1 by Series.isinand 聚合用于由聚合值GroupBy.transform填充sum并除以的新列Series.div

s1 = df['value'].where(df['input'].eq(1), 0)
s2 = (df.assign(value = df['value'].where(df['input'].isin([0,1]), 0))
        .groupby(['type','module'])['value'].transform('sum'))
df['pct '] = s1.div(s2)
print (df)
  type module   item  value  input      pct 
0    A      a  item1      2      1  0.400000
1    A      a  item2      3      0  0.000000
2    A     aa  item3      4      1  0.571429
3    A     aa  item4      3      0  0.000000
4    A     aa  item5      1     -1  0.000000
5    B      b  item1      5      0  0.000000
6    B      b  item2      1     -1  0.000000
7    B     bb  item3      3      0  0.000000
8    B     bb  item4      3      1  0.300000
9    B     bb  item5      4      0  0.000000

对于第二个DataFrame添加 2 个新列DataFrame.assign,聚合sum和最后一个除以DataFrame.pop使用和删除列value

df2 = (df.assign(value = df['value'].where(df['input'].isin([0,1]), 0),
                 pct = df['value'].where(df['input'].eq(1), 0))
         .groupby(['type','module'])[['value','pct']]
         .sum()
         .assign(pct = lambda x: x['pct'].div(x.pop('value')))
         .reset_index())

print (df2)
  type module       pct
0    A      a  0.400000
1    A     aa  0.571429
2    B      b  0.000000
3    B     bb  0.300000

推荐阅读