【问题标题】:How to perform conditional aggregation AFTER groupby in python?如何在 python 中的 groupby 之后执行条件聚合?
【发布时间】:2023-01-23 17:44:30
【问题描述】:

我的第一列是“年”。我的第二列是“银行”。我的最后一列是“价值”。 我想为每个“银行”获取 year=2003 的 VALUE 总和,并将其显示在新列中。 即如果我的起始数据框可以用以下代码表示:

df = pd.DataFrame({'year' : [2001, 2002, 2003, 2001, 2002, 2003, 2001, 2002, 2003, 2001, 2002, 2003],
               'bank' : ['sbi', 'sbi', 'sbi', 'sbi', 'sbi', 'sbi', 'icici', 'icici', 'icici', 'icici', 'icici', 'icici'],
                   'amt' : [1000, 2000, 3000, 4000, 5000, 6000,1,2,3,4,5,6]
                  })

那么最终的输出可以用下面的代码来表示:

df = pd.DataFrame({'year' : [2001, 2002, 2003, 2001, 2002, 2003, 2001, 2002, 2003, 2001, 2002, 2003],
                   'bank' : ['sbi', 'sbi', 'sbi', 'sbi', 'sbi', 'sbi', 'icici', 'icici', 'icici', 'icici', 'icici', 'icici'],
                       'amt' : [1000, 2000, 3000, 4000, 5000, 6000,1,2,3,4,5,6],
                       'amt_2003': [9000, 9000, 9000, 9000, 9000, 9000, 9, 9, 9, 9, 9, 9]
                      })

即 - 对于“sbi”,“year”=2003 中的总“value”为 3000+6000=9000,它显示在“sbi”的所有行中。同样,我对所有行的“icici”都得到 9。

使用 groupby('bank') 语句后,我无法使用条件总和。

【问题讨论】:

    标签: python python-3.x pandas jupyter-notebook data-science


    【解决方案1】:

    你可能想执行groupby.sum,然后是unstackmerge

    df2 = df.groupby(['year', 'bank']).sum().unstack('year')
    df2.columns = df2.columns.map(lambda x: f'{x[0]}_{x[1]}')
    
    out = df.merge(df2.reset_index())
    

    输出:

        year   bank   amt  amt_2001  amt_2002  amt_2003
    0   2001    sbi  1000      5000      7000      9000
    1   2002    sbi  2000      5000      7000      9000
    2   2003    sbi  3000      5000      7000      9000
    3   2001    sbi  4000      5000      7000      9000
    4   2002    sbi  5000      5000      7000      9000
    5   2003    sbi  6000      5000      7000      9000
    6   2001  icici     1         5         7         9
    7   2002  icici     2         5         7         9
    8   2003  icici     3         5         7         9
    9   2001  icici     4         5         7         9
    10  2002  icici     5         5         7         9
    11  2003  icici     6         5         7         9
    

    注意。如果您有多个输入列,这不仅仅适用于“amt”。

    中级df2

           amt_2001  amt_2002  amt_2003
    bank                               
    icici         5         7         9
    sbi        5000      7000      9000
    

    要限制保留的年份,请使用 loc 切片:

    keep = [2003]
    
    df2 = df.groupby(['year', 'bank']).sum().loc[keep].unstack('year')
    df2.columns = df2.columns.map(lambda x: f'{x[0]}_{x[1]}')
    
    out = df.merge(df2.reset_index())
    

    输出:

        year   bank   amt  amt_2003
    0   2001    sbi  1000      9000
    1   2002    sbi  2000      9000
    2   2003    sbi  3000      9000
    3   2001    sbi  4000      9000
    4   2002    sbi  5000      9000
    5   2003    sbi  6000      9000
    6   2001  icici     1         9
    7   2002  icici     2         9
    8   2003  icici     3         9
    9   2001  icici     4         9
    10  2002  icici     5         9
    11  2003  icici     6         9
    

    【讨论】:

      【解决方案2】:

      Series.map 用于2003 的过滤行,聚合sum 用于列amt

      df['amt_2003'] = df['bank'].map(df[df['year'].eq(2003)].groupby('bank')['amt'].sum())
      

      或者使用 Series.where 将非 2003 值替换为 0 并为新列使用 GroupBy.transform

      df['amt_2003'] = df['amt'].where(df['year'].eq(2003),0).groupby(df['bank']).transform('sum')
      print (df)
          year   bank   amt  amt_2003
      0   2001    sbi  1000      9000
      1   2002    sbi  2000      9000
      2   2003    sbi  3000      9000
      3   2001    sbi  4000      9000
      4   2002    sbi  5000      9000
      5   2003    sbi  6000      9000
      6   2001  icici     1         9
      7   2002  icici     2         9
      8   2003  icici     3         9
      9   2001  icici     4         9
      10  2002  icici     5         9
      11  2003  icici     6         9
      

      Fora 所有列都使用 DataFrame.pivot_tableDataFrame.add_prefixDataFrame.join

      df1 = (df.join(df.pivot_table(index='bank', columns='year',values='amt', aggfunc='sum')
                       .add_prefix('amt_'), on='bank'))
      print (df1)
          year   bank   amt  amt_2001  amt_2002  amt_2003
      0   2001    sbi  1000      5000      7000      9000
      1   2002    sbi  2000      5000      7000      9000
      2   2003    sbi  3000      5000      7000      9000
      3   2001    sbi  4000      5000      7000      9000
      4   2002    sbi  5000      5000      7000      9000
      5   2003    sbi  6000      5000      7000      9000
      6   2001  icici     1         5         7         9
      7   2002  icici     2         5         7         9
      8   2003  icici     3         5         7         9
      9   2001  icici     4         5         7         9
      10  2002  icici     5         5         7         9
      11  2003  icici     6         5         7         9
      

      【讨论】:

        猜你喜欢
        • 2020-01-07
        • 2015-11-27
        • 2020-04-29
        • 2021-11-24
        • 2017-07-04
        • 1970-01-01
        • 2016-03-16
        • 2020-07-04
        • 2019-08-10
        相关资源
        最近更新 更多