如果另一列中的行包含列表中的项目,则计算一列中的值的总和

Posted

技术标签:

【中文标题】如果另一列中的行包含列表中的项目,则计算一列中的值的总和【英文标题】: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

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

【问题讨论】:

【参考方案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
    

    计算 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

    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
    

    最后一步是计算新列:

    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

【讨论】:

以上是关于如果另一列中的行包含列表中的项目,则计算一列中的值的总和的主要内容,如果未能解决你的问题,请参考以下文章

在另一列满足条件后计算一列中的值

如果另一列中的值较差,则汇总一列(没有 for 循环)

检查一列中的值是不是存在于另一列中,如果存在,则将另一列中的值复制到新列中

仅返回一列中的日期与另一列中的日期最接近的行?

PySpark查找另一列中是否存在一列中的模式

在python中,我如何对一列中每个值与另一列中的值发生的次数(多少行)建立矩阵?