【问题标题】:Compute the sum of values in one column, if row in another column contains item in list如果另一列中的行包含列表中的项目,则计算一列中的值的总和
【发布时间】:2022-01-05 06:51:30
【问题描述】:

在 python 中,我有一个如下所示的数据框:

Column1               Column2
[a,b,c,d]             4    
[a,f,g]               3
[b,c]                 6
[a,c,d]               5

我想计算第三列,每次在 Column1 中存在一个项目时,它都会在 Column2 中添加值(例如,在第一行中,它将是 a=4+3+5,b=4 +6,c=5+6+5,d=4+5,所以总共4+3+5+4+6+5+6+5+4+5=47):

Column1               Column2     Column3
[a,b,c,d]             4           47
[a,f,g]               3           21
[b,c]                 6           26
[a,c,d]               5           37

我在查询和索引方面尽了最大努力,但没有成功,提前谢谢你!

【问题讨论】:

    标签: python pandas list dataframe numpy


    【解决方案1】:

    让我们从更容易理解的版本开始,一步一步来。

    1. 分解Column1

      wrk = df.explode(column='Column1')
      

      结果是:

        Column1  Column2
      0       a        4
      0       b        4
      0       c        4
      0       d        4
      1       a        3
      1       f        3
      1       g        3
      2       b        6
      2       c        6
      3       a        5
      3       c        5
      3       d        5
      
    2. 计算 Column1 中列表中每个元素的权重:

      weight = wrk.groupby('Column1').sum().rename(columns={'Column2': 'Weight'})
      

      结果是:

               Weight
      Column1        
      a            12
      b            10
      c            15
      d             9
      f             3
      g             3
      

      请注意计数的一些差异,例如c 的重量 是 4 + 6 + 5 = 15

    3. wrk 中的 Column1weight 结合起来:

       wrk2 = wrk[['Column1']].join(weight, on='Column1')
      

      结果是:

        Column1  Weight
      0       a      12
      0       b      10
      0       c      15
      0       d       9
      1       a      12
      1       f       3
      1       g       3
      2       b      10
      2       c      15
      3       a      12
      3       c      15
      3       d       9
      
    4. 最后一步是计算新列:

      df['Column3'] = wrk2.groupby(level=0).Weight.sum()
      

      结果是:

              Column1  Column2  Column3
      0  [a, b, c, d]        4       46
      1     [a, f, g]        3       18
      2        [b, c]        6       25
      3     [a, c, d]        5       36
      

    但是如果你想要更简洁的代码,你可以“压缩”上面的 解决办法:

    wrk = df.explode(column='Column1')
    df['Column3'] = wrk[['Column1']].join(wrk.groupby('Column1').sum().rename(
        columns={'Column2': 'Weight'}), on='Column1').groupby(level=0).Weight.sum()
    

    【讨论】:

      【解决方案2】:
      df = pd.DataFrame({'Column1': [['a', 'b', 'c', 'd'], ['a', 'f', 'g'], ['b', 'c'], ['a', 'c', 'd']],
                         'Column2': [4, 3, 6, 5]})
      df1 = df.explode('Column1')
      df['Column3'] = df1.groupby(level=0).apply(
          lambda d: d.Column1.apply(lambda x: df1.loc[df1.Column1 == x, 'Column2'].sum()).sum())
      print(df)
      
              Column1  Column2  Column3
      0  [a, b, c, d]        4       46
      1     [a, f, g]        3       18
      2        [b, c]        6       25
      3     [a, c, d]        5       36
      

      【讨论】:

        【解决方案3】:

        尝试使用explode,然后创建映射字典并返回groupby

        s = df.explode('Column1')
        d = s.groupby('Column1')['Column2'].sum()
        s['new'] = s['Column1'].map(d)
        out = s.groupby(level=0).agg({'Column1':list,'Column2':'first','new':'sum'})
        out
                Column1  Column2  new
        0  [a, b, c, d]        4   46
        1     [a, f, g]        3   18
        2        [b, c]        6   25
        3     [a, c, d]        5   36
        

        注意:

        c = 4+6+5

        【讨论】:

          猜你喜欢
          • 2020-08-06
          • 2019-05-13
          • 2011-08-13
          • 2020-11-24
          • 2019-02-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多