提问人:Peter Bright 提问时间:5/12/2023 最后编辑:CorralienPeter Bright 更新时间:5/12/2023 访问量:32
如果单独数据帧中的列值匹配,则将单独的列相加(如果列值大于零)
If column value in separate dataframes match, add separate columns together (if column value is greater than zero)
问:
我有两个数据帧,我们称它们为 a 和 b。我想对它们进行排序并提取出现在两个数据帧中的“颜色”列中的值,然后将数据帧 a 中的列“scalar_y”添加到数据帧 b,并将数据帧 a 中的列“标量 z”添加到数据帧 b,但前提是数据帧 b 中的现有值大于零。
import pandas as pd
import numpy as np
dict1 = {'color':['purple','yellow','red','green','blue', 'violet','black'], 'scalar_y':[1,2,0,5,7,9,10], 'scalar_z':[2,4,6,8,10,12,10]}
a = pd.DataFrame(dict1)
dict2 = {'color':['purple','yellow','yellow','green','blue', 'violet','violet'], 'x':['ducks','geese','moose','bear','acorn','seagull','worm'],'y':[10,20,0,50,70,90,100], 'z':[20,40,60,80,100,120,0]}
b = pd.DataFrame(dict2)
所需的输出如下所示:
到目前为止,我所拥有的是一个 forloop,它挑选出共享的颜色,但我无法让添加工作:
empty = pd.DataFrame()
for color in a.color:
new_df = b.loc[b['color'].str.contains(color)]
new_df['y'] = new_df['y'].apply(lambda x: '0' if x==0 else new_df['y'] = new_df['y'].add(a['scalar_y'], axis=0))
empty = pd.concat([empty,new_df])
#print(new_df)
empty
如果这可行,我会为 new_df['z'] 设置相同的 lambda 函数。最终,我想用生成的“空”数据帧更新 b,也许有一种更直接的方法可以做到这一点。我的编码技能是新手,为这里的糟糕尝试道歉。
答:
0赞
jezrael
5/12/2023
#1
使用带有左连接的合并
并在 DataFrame.assign
中添加列,如果像 Series.mask 一样,要删除列,请使用 DataFrame.pop
:0
c = (b.merge(a, on='color', how='left')
.assign(y = lambda x: x.y.mask(x.y.gt(0), x.y.add(x.pop('scalar_y'))),
z = lambda x: x.z.mask(x.z.gt(0), x.z.add(x.pop('scalar_z')))))
print (c)
color x y z
0 pruple ducks 11 22
1 yellow geese 22 44
2 yellow moose 0 64
3 green bear 55 88
4 blue acorn 77 110
5 violet seagull 99 132
6 violet worm 109 0
映射的另一个想法:
c = (b.assign(y=lambda x:x.y.mask(x.y.gt(0),
x.y.add(x.color.map(a.set_index('color')['scalar_y']))),
z=lambda x:x.z.mask(x.z.gt(0),
x.z.add(x.color.map(a.set_index('color')['scalar_z'])))))
print (c)
color x y z
0 pruple ducks 11 22
1 yellow geese 22 44
2 yellow moose 0 64
3 green bear 55 88
4 blue acorn 77 110
5 violet seagull 99 132
6 violet worm 109 0
评论