基于category和location匹配填充DataFrame新列并计算衍生字段
问题解决:DataFrame匹配填充与计算字段实现
需求说明
需要实现:当df1的category与df2的CATEGORY、df1的location与df2的LOCATION匹配时,将df2的VALUE填充到df1的新列New中,随后计算calculatedfield = df1['v1']/df1['New'],且必须保留df1所有行(不能因为匹配不到删除行)。
报错情况
尝试使用以下代码时触发错误:
df1['New'] = np.where((df1['category'] == df2['CATEGORY']) & (df1['location'] == df2['location']), df2['VALUE'], None)
错误信息:
ValueError: Can only compare identically-labeled Series objects
错误原因
np.where里直接用==对比两个Series时,要求两个Series的索引完全一致、行数相同,但df1有8行,df2只有4行,索引和长度都不匹配,所以触发这个错误。这种逐元素对比的方式不适合跨不同长度DataFrame的匹配场景。
解决方案
用pandas的merge方法做左连接,左连接会自动保留左表(df1)的所有行,同时按指定键匹配右表(df2)的数据,完美满足需求。
完整代码
import pandas as pd # 构造示例数据(实际使用时替换为你的真实数据) df1 = pd.DataFrame({ 'category': ['A', 'A', 'A', 'A', 'B', 'B', 'B', 'B'], 'location': ['loc1', 'loc1', 'loc2', 'loc2', 'loc1', 'loc1', 'loc2', 'loc2'], 'type': [1, 2, 1, 2, 1, 2, 1, 2], 'v1': [2, 4, 6, 8, 10, 12, 14, 16] }) df2 = pd.DataFrame({ 'CATEGORY': ['A', 'A', 'B', 'B'], 'LOCATION': ['loc1', 'loc2', 'loc1', 'loc2'], 'VALUE': [50, 30, 70, 90] }) # 左连接:保留df1所有行,按指定键匹配df2的数据 df_merged = pd.merge(df1, df2, left_on=['category', 'location'], right_on=['CATEGORY', 'LOCATION'], how='left') # 重命名VALUE列为New df_merged['New'] = df_merged['VALUE'] # 计算目标字段,保留两位小数 df_merged['calculatedfield'] = (df_merged['v1'] / df_merged['New']).round(2) # 整理输出列,移除多余的匹配键列 result = df_merged[['category', 'location', 'type', 'v1', 'New', 'calculatedfield']] print(result)
输出结果
| category | location | type | v1 | New | calculatedfield |
|---|---|---|---|---|---|
| A | loc1 | 1 | 2 | 50 | 0.04 |
| A | loc1 | 2 | 4 | 50 | 0.08 |
| A | loc2 | 1 | 6 | 30 | 0.20 |
| A | loc2 | 2 | 8 | 30 | 0.27 |
| B | loc1 | 1 | 10 | 70 | 0.14 |
| B | loc1 | 2 | 12 | 70 | 0.17 |
| B | loc2 | 1 | 14 | 90 | 0.16 |
| B | loc2 | 2 | 16 | 90 | 0.18 |
内容的提问来源于stack exchange,提问作者pluret
相关产品推荐
相关产品推荐

