基于条件匹配Pandas列:按区域+最小距离填充Category列
Pandas无循环实现区域匹配+最小距离差映射Category列
需求说明
现有两个Pandas DataFrame:
- 查找表
lookup_data_df:存储各区域对应的Category及参考距离 - 待处理表
actual_df:需新增Category列,规则如下:- 优先匹配相同区域,选择与当前行
Distance差值绝对值最小的Category;若差值相同,选参考距离更小的 - 若区域在查找表中不存在,直接在全局范围内选择与当前行
Distance差值绝对值最小的Category;若差值相同,选参考距离更小的
- 优先匹配相同区域,选择与当前行
生成测试数据
import pandas as pd # 生成查找表 lookup_data = {'Category' : ['A1', 'A2', 'B1', 'C1', 'D1', 'D2'], 'Region':['A', 'A', 'B', 'C', 'D', 'D'], 'Distance':[109, 200, 300, 400, 500, 600]} lookup_data_df = pd.DataFrame(lookup_data) # 生成待处理数据表 actual_data = {'Region':['A', 'A', 'B', 'C', 'D', 'D', 'E'], 'Distance':[95, 199, 10, 350, 550, 560, 200]} actual_df = pd.DataFrame(actual_data)
无循环解决方案
# 给待处理表添加唯一索引,用于后续分组 actual_df['idx'] = actual_df.index # 笛卡尔积合并两个表,生成所有可能的匹配组合 merged = actual_df.merge(lookup_data_df, how='cross', suffixes=('_actual', '_lookup')) # 计算距离差值绝对值,标记是否同区域 merged['abs_diff'] = abs(merged['Distance_actual'] - merged['Distance_lookup']) merged['same_region'] = merged['Region_actual'] == merged['Region_lookup'] # 定义分组匹配逻辑:优先同区域,再按差值、参考距离排序取最优 def get_best_match(group): same_region_rows = group[group['same_region']] if not same_region_rows.empty: return same_region_rows.sort_values(['abs_diff', 'Distance_lookup']).iloc[0]['Category'] else: return group.sort_values(['abs_diff', 'Distance_lookup']).iloc[0]['Category'] # 分组应用匹配逻辑,获取每个行的Category result = merged.groupby('idx').apply(get_best_match).reset_index(name='Category') # 合并回原表,整理列顺序 final_df = actual_df.merge(result, on='idx').drop('idx', axis=1) final_df = final_df[['Region', 'Category', 'Distance']]
验证结果
生成预期输出并对比:
# 生成预期输出表 expected_data = {'Region':['A', 'A', 'B', 'C', 'D', 'D', 'E'], 'Category' : ['A1', 'A2', 'B1', 'C1', 'D1', 'D2', 'A2'], 'Distance':[95, 199, 10, 350, 550, 560, 200]} expected_data_df = pd.DataFrame(expected_data) # 检查结果是否一致 print(final_df.equals(expected_data_df)) # 输出 True
内容的提问来源于stack exchange,提问作者Lopez
相关产品推荐
相关产品推荐

