![](/img/trans.png)
[英]Update a dataframe(df1) column with value from another dataframe(df2) column when a key column in df1 matches to multiple columns in df2
[英]How can I add a new column to a dataframe (df1) that is the sum of multiple lookup values from df1 in another dataframe (df2)
假设我有 2 个数据框:
df1
id guid name item1 item2 item3 item4 item5 item6 item7 item8 item9
0 3031958124 85558-261955282 Alonso 85558-57439 85558-54608 85558-91361 85558-40647 85558-41305 85558-79979 85558-33076 85558-89956 85558-12554
1 3031958127 85558-261955282 Jeff 85558-57439 85558-39280 85558-91361 85558-55987 85558-83083 85558-79979 85558-33076 85558-41872 85558-12554
2 3031958129 85558-261955282 Mike 85558-57439 85558-39280 85558-91361 85558-55987 85558-40647 85558-79979 85558-33076 85558-88297 85558-12534
...
df2 其中item_lookup
是索引
item_type cost value target
item_lookup
85558-57439 item1 9500 25.1 1.9
85558-54608 item2 8000 18.7 0.0
85558-91361 item3 7000 16.5 0.9
...
我想使用 item_lookup ( df2
) 为每个 item1 到 item9 添加cost
、 value
和target
的总和,并将其存储为 df1 上的列。
所以结果应该是这样的:df1
id guid name item1 item2 item3 item4 item5 item6 item7 item8 item9 cost value target
0 3031958124 85558-261955282 Alonso 85558-57439 85558-54608 85558-91361 85558-40647 85558-41305 85558-79979 85558-33076 85558-89956 85558-12554 58000 192.5 38.3
1 3031958127 85558-261955282 Jeff 85558-57439 85558-39280 85558-91361 85558-55987 85558-83083 85558-79979 85558-33076 85558-41872 85558-12554 59400 183.2 87.7
2 3031958129 85558-261955282 Mike 85558-57439 85558-39280 85558-91361 85558-55987 85558-40647 85558-79979 85558-33076 85558-88297 85558-12534 58000 101.5 18.1
...
我尝试过使用.map
在线遵循类似的解决方案,但是这些示例仅适用于单列,而我试图对 9 列的值求和。
您可以通过使用df.apply
来做到这一点,基本上循环遍历行,然后循环遍历行中的项目并计算总和
因为我不能使用你的 dfs 因为它们不完整,所以我做了我的。
给定df1
:
item1 item2 item3
0 b e j
1 d a d
2 j b a
3 c j f
4 e f c
5 a d b
6 f c e
和df2
cost value target
item_lookup
a 19 20 12
b 16 14 14
c 20 18 18
d 17 12 14
e 20 15 17
f 19 20 12
j 11 17 12
您可以使用以下 function 来获得您需要的东西
def add_items(row):
row["cost"] = row["target"] = row["value"] = 0
# get the columns that have item in the name
cols = [col for col in df1.columns if "item" in col]
# get each of the columns look it up in df2 and add it to our new cols
for col in cols:
item_lookup = row[col]
lookup_result = df2.loc[item_lookup]
row["cost"] += lookup_result["cost"]
row["target"] += lookup_result["target"]
row["value"] += lookup_result["value"]
return row
然后应用它
>>> df1.apply(add_items, axis=1)
item1 item2 item3 cost target value
0 b e j 47 43 46
1 d a d 53 40 44
2 j b a 46 38 51
3 c j f 50 42 55
4 e f c 59 47 53
5 a d b 52 40 46
6 f c e 59 47 53
我在这里得到了一个更简单的解决方案。 首先,将 cost、target 和 value 对应的item_lookup
值保存到字典中。 然后使用.map()
和.sum()
创建列:
df2.reset_index(drop=False, inplace=True)
map_cost = dict(zip(df2['item_lookup'], df2['cost']))
map_value = dict(zip(df2['item_lookup'], df2['value']))
map_target = dict(zip(df2['item_lookup'], df2['target']))
df1['cost'] = df1.apply(lambda x: x.map(map_cost)).sum(axis=1)
df1['value'] = df1.apply(lambda x: x.map(map_value)).sum(axis=1)
df1['target'] = df1.apply(lambda x: x.map(map_target)).sum(axis=1)
df1
Output:
id guid name item1 item2 item3 cost value target
0 3031958124 85558-261955282 Alonso 85558-57439 85558-54608 85558-91361 24500.0 60.3 2.8
1 3031958127 85558-261955282 Jeff 85558-57439 85558-39280 85558-91361 16500.0 41.6 2.8
2 3031958129 85558-261955282 Mike 85558-57439 85558-39280 85558-91361 16500.0 41.6 2.8
我更喜欢以下解决方案,它具有@ali bakhtiari 和@zaki98 提出的解决方案的元素,但更加明确、高效和灵活。 使用applymap
因为项目查找对于所有项目列都是相同的,假设df2
中的item_lookup
唯一标识每一行(所有解决方案都假设这一点); 但是,我提出的解决方案还处理df1
中不存在的item_lookup
的情况df2
。 对于df1
和 `df2 如下,
将列定义为 sum、 sum_cols
和df1
中的 item 列、 item_cols
,然后 append 将每个求和列定义为df1
,如下所示:
sum_cols = ['cost', 'value', 'target']
item_cols = [col for col in df1.columns if 'item' in col]
df2.set_index('item_lookup', inplace=True)
for sc in sum_cols:
df1[sc] = df1[item_cols] \
.applymap(lambda x: df2.at[x, sc] if x in df2.index else 0) \
.sum(axis=1)
这个问题似乎也是 over loc
性能at
的一个很好的用例,因为每次只查找一个数值(参见这篇SO 帖子)。 没有必要将item_lookup
设置为df2
上的索引,但这样做应该会提高大型数据集的性能。 如果df1
中的item_lookup
不存在于df2
中,您也可以替换为NaN
,例如,这样可以计算缺少的item_lookup
值的数量,而额外的工作量最少。
Output df1
:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.