【问题标题】:Groupby multiple columns and calculate percentage of sums in PandasGroupby多列并计算Pandas中总和的百分比
【发布时间】:2020-07-20 07:36:06
【问题描述】:

给定一个数据集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

我需要根据以下逻辑计算pctsum:首先,我们只取valueinput01 作为有效值。然后我需要groupbytype, module来计算总和的百分比,例如A-a-item1第一行的pct2/(2 + 3) = 0.4计算,A-aa-item14/(4 + 3) = 0.57计算,不除以@987654335 @ 因为A-aa-item3 的输入值是-1,所以它被排除在外。 df2 中的 sum 列由 groupby type module 然后计算 sum 的总和。

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

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

【问题讨论】:

  • 所以有 2 个掩码 - 首先比较相等 01,然后比较 1,因此 -1, 0 的行在 pct 中设置为 0 ?

标签: python-3.x pandas dataframe pandas-groupby


【解决方案1】:

您可以将不匹配条件替换为Series.eq 以将10 进行比较,并将0, 1Series.isin 进行比较,而将GroupBy.transformsum 一起用于填充新列按聚合值除以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

第二个DataFrameDataFrame.assign 添加2 个新列,聚合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

【讨论】:

  • 对不起,我在您的代码中发现了一个小问题,正如我在上一个问题中发布的那样,当我们为 df 计算 pct 时,我们需要从总和中排除 input=-1 的值。
  • @xarena - 输出有问题?
  • stackoverflow.com/questions/62989116/…。我也需要在 groupby 之后实现这个。
  • @xarena - 所以你需要将 pct = df['value'].where(df['input'].eq(1), 0) 更改为 pct = df['value'].where(df['input'] != -1, 0)
  • 对不起,我的错误,你的代码是完美的,我把value改成了另一个名字,但在某些代码中它仍然存在。
猜你喜欢
  • 1970-01-01
  • 2022-06-13
  • 1970-01-01
  • 2018-03-24
  • 2019-01-26
  • 1970-01-01
  • 2022-11-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多