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



在python中,我有一个数据帧,看起来像:

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

我想计算第三列,每当第1列中有一个项目时,它会将第2列中的值相加(例如,在第一行中,它将是a=4+3+5,b=4+6,c=5+6+5,d=4+5,所以总共4+3+5+4+6+6+5+5+4+5+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

我已经尽了最大努力进行查询和索引,但没有成功,提前感谢!

尝试使用explode,然后创建映射dict和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

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

让我们从更容易理解的版本开始,循序渐进。

  1. 分解第1列

    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. 根据第1列中的列表计算每个元素的权重:

    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加入第1列权重

    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()

最新更新