【问题标题】:Calculating percentage share for each Pandas group and converting to new columns计算每个 Pandas 组的百分比份额并转换为新列
【发布时间】:2023-02-13 14:17:53
【问题描述】:

我有这个数据框:

import pandas as pd


df = pd.DataFrame({"ID": ["123", "456", "123", "456", "123", "456", "456", "456", "456", "123"],
                    "number": [2,1,5,2,4,5,2,1,6,7],
                    "name": ["apple", "orange", "orange", "pear", "pear", "apple", "lemon", "apple", "lemon", "apple"]
})

    ID  number    name
0  123       2   apple
1  456       1  orange
2  123       5  orange
3  456       2    pear
4  123       4    pear
5  456       5   apple
6  456       2   lemon
7  456       1   apple
8  456       6   lemon
9  123       7   apple

我想计算我命名列的每个元素的百分比份额,按 ID 分组。

DataFrame 的最终外观应该有这些列:

ID、数字、苹果、橙子、梨子、柠檬

因此,来自 name 列的值正在成为列名。这些列应该具有的值是百分比份额,例如:

编号 123 我有这些数值:2+5+4+7 = 18

所以

apple has: (2+7) / 18 = 0.50
orange has: 5 / 18 = 0.27
pear has: 4 / 18 = 0.23
lemon has: 0   

ID   apple   orange   pear   lemon
123  0.5     0.27     0.23    0

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    您可以将 crosstabnormalize='index' 一起使用:

    out = pd.crosstab(df['ID'], df['name'], values=df['number'],
                      aggfunc='sum', normalize='index')
    

    输出:

    name     apple     lemon    orange      pear
    ID                                          
    123   0.500000  0.000000  0.277778  0.222222
    456   0.352941  0.470588  0.058824  0.117647
    

    【讨论】:

      【解决方案2】:

      由不同的组使用GroupBy.transformSeries.div

      df['Perc'] = (df.groupby(['ID','name'])['number'].transform('sum')
                      .div(df.groupby('ID')['number'].transform('sum')))
      print (df)
          ID  number    name      Perc
      0  123       2   apple  0.500000
      1  456       1  orange  0.058824
      2  123       5  orange  0.277778
      3  456       2    pear  0.117647
      4  123       4    pear  0.222222
      5  456       5   apple  0.352941
      6  456       2   lemon  0.470588
      7  456       1   apple  0.352941
      8  456       6   lemon  0.470588
      9  123       7   apple  0.500000
      

      如果需要另一个输出,请使用 DataFrame.pivot_table 并除以 sum

      df = df.pivot_table(index='ID', 
                          columns='name', 
                          values='number', 
                          aggfunc='sum', 
                          fill_value=0)
      df = df.div(df.sum(axis=1), axis=0)
      print (df)
      name     apple     lemon    orange      pear
      ID                                          
      123   0.500000  0.000000  0.277778  0.222222
      456   0.352941  0.470588  0.058824  0.117647
      

      【讨论】:

        【解决方案3】:
        def function1(dd:pd.DataFrame):
            ss1=dd.groupby("name").number.sum().div(dd.number.sum())
            return ss1.round(2)
        
        df.groupby('ID').apply(function1).unstack(level=1,fill_value=0)
        

        出去:

        name  apple  lemon  orange  pear
        ID                              
        123    0.50   0.00    0.28  0.22
        456    0.35   0.47    0.06  0.12
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-05-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-06-20
          • 2022-10-02
          相关资源
          最近更新 更多