如何按匹配得分排序DataFrame中的多组匹配相关列?
企业名称匹配结果排序方案
问题说明
现有一个企业名称匹配结果的DataFrame,结构如下:
- 包含
original_name列,存储原始企业名称 - 剩余列按匹配组划分,每组对应
match_name_X、score_X、match_index_X三列(X从0到N),代表一组匹配结果
需要生成新的DataFrame,满足:
original_name列保持不变- 后续的匹配组按得分从高到低排序
- 得分相同时,原位置更靠左的匹配组优先级更高
示例输入表格:
| index | original_name | match_name_0 | score_0 | match_index_0 | match_name_1 | score_1 | match_index_1 | match_name_2 | score_2 | match_index_2 | match_name_3 | score_3 | match_index_3 | match_name_4 | score_4 | match_index_4 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | aberdeen asset management plc | aberdeen asset management sa | 100 | 2114 | aberdeen asset management plc esop | 100 | 2128 | aberdeen asset management inc | 100 | 2123 | aberdeen asset management spain | 71.18779356 | 2132 | aberdeen asset management ireland | 69.50514818 | 2125 |
| 2 | agi partners llc | agi partners llc | 100 | 5274 | agi partners llc | 100 | 5273 | agr partners llc | 57.51100704 | 5378 | aci partners llc | 53.45090217 | 3097 | avi partners llc | 53.45090217 | 17630 |
| 3 | alberta investment management corporation | alberta investment management corporation | 100 | 6754 | alberta investment management corporation pension arm | 100 | 6755 | anchor investment management corporation | 17.50748486 | 10682 | cbc investment management corporation | 11.79760839 | 36951 | harvest investment management corporation | 31.70316571 | 85547 |
解决方案
以下是基于Pandas的实现代码,核心思路是将每个匹配组作为独立单元,按规则排序后重新拼接:
import pandas as pd def sort_matches(row): # 提取原始名称 original = row['original_name'] # 提取所有匹配组数据,并记录原始位置 match_groups = [] total_groups = (len(row) - 1) // 3 # 总匹配组数 for x in range(total_groups): match_name = row[f'match_name_{x}'] score = row[f'score_{x}'] match_idx = row[f'match_index_{x}'] match_groups.append( ( -score, x, match_name, score, match_idx ) ) # 排序:先按负score降序(即score从高到低),再按原始位置x升序 match_groups.sort() # 展开排序后的结果,去掉排序用的key sorted_data = [] for item in match_groups: sorted_data.extend( [item[2], item[3], item[4]] ) # 拼接原始名称和排序后的匹配数据 return pd.Series( [original] + sorted_data ) # 构造示例DataFrame(替换为你的实际数据) data = { 'original_name': [ 'aberdeen asset management plc', 'agi partners llc', 'alberta investment management corporation' ], 'match_name_0': [ 'aberdeen asset management sa', 'agi partners llc', 'alberta investment management corporation' ], 'score_0': [100, 100, 100], 'match_index_0': [2114, 5274, 6754], 'match_name_1': [ 'aberdeen asset management plc esop', 'agi partners llc', 'alberta investment management corporation pension arm' ], 'score_1': [100, 100, 100], 'match_index_1': [2128, 5273, 6755], 'match_name_2': [ 'aberdeen asset management inc', 'agr partners llc', 'anchor investment management corporation' ], 'score_2': [100, 57.51100704, 17.50748486], 'match_index_2': [2123, 5378, 10682], 'match_name_3': [ 'aberdeen asset management spain', 'aci partners llc', 'cbc investment management corporation' ], 'score_3': [71.18779356, 53.45090217, 11.79760839], 'match_index_3': [2132, 3097, 36951], 'match_name_4': [ 'aberdeen asset management ireland', 'avi partners llc', 'harvest investment management corporation' ], 'score_4': [69.50514818, 53.45090217, 31.70316571], 'match_index_4': [2125, 17630, 85547] } df = pd.DataFrame(data) # 应用排序函数 sorted_df = df.apply(sort_matches, axis=1) # 重新设置列名 total_groups = (len(df.columns) - 1) // 3 new_columns = ['original_name'] for x in range(total_groups): new_columns.extend( [f'match_name_{x}', f'score_{x}', f'match_index_{x}'] ) sorted_df.columns = new_columns print(sorted_df)
代码说明
- 提取匹配组:遍历每行数据,将每个
match_name_X、score_X、match_index_X组合成一个单元,并记录原始位置x - 排序逻辑:使用
(-score, x)作为排序key,负score实现得分降序,原始位置x保证得分相同时原位置靠前的组优先 - 重新拼接:将排序后的匹配组展开,与原始名称拼接成新行,最后重置列名保持原有格式
运行后,示例中第三行的匹配组会按得分排序为:score=100的两组 → score=31.7的组 → score=17.5的组 → score=11.8的组,符合要求。
内容的提问来源于stack exchange,提问作者novawaly
相关产品推荐
相关产品推荐

