如何用Pandas将小DataFrame与查找表匹配并添加对应SMS列?
Pandas按多列匹配查找表添加对应列的解决方案
问题场景
现有两个Pandas DataFrame:
- 小型数据表格
df_size,包含diameter_mean、diameter_min、diameter_max三列 - 查找表
df_lookup,包含diameter(匹配键)和对应的SMS值
需要为df_size添加三列SMS、SMS_min、SMS_max,分别对应三列直径值匹配到的SMS值。此前尝试merge方法出现ValueError,apply/map方法出现KeyError,目标输出格式如下:
diameter_mean diameter_min diameter_max SMS SMS_min SMS_max 0 0.510 0.450 0.540 0.021791 0.021548 0.022038 1 0.899 0.820 1.150 1.302340 1.296070 2.311770 2 1.745 1.587 2.020 3.498933 4.144621 3.512665 3 2.020 1.745 2.405 3.512665 3.498933 3.610773
解决方案
方法1:基于字典映射(最简洁)
先将查找表转换为键值对字典,再用map方法为每列匹配对应值:
import pandas as pd # 定义原始DataFrame df_size = pd.DataFrame([[0.510,0.450,0.540], [0.899,0.820,1.150], [1.745,1.587,2.020], [2.020,1.745,2.405], ], columns=['diameter_mean', 'diameter_min','diameter_max']) df_lookup = pd.DataFrame([[0.450,0.021548], [0.510,0.021791], [0.540,0.022038], [0.565,0.022289], [0.695,0.022545], [0.720,0.034321], [0.770,1.292340], [0.820,1.296070], [0.899,1.302340], [1.150,2.311770], [1.361,3.325140], [1.587,4.144621], [1.745,3.498933], [2.020,3.512665], [2.405,3.610773], ], columns=['diameter', 'SMS']) # 将查找表转为字典 sms_mapping = df_lookup.set_index('diameter')['SMS'].to_dict() # 为每列匹配SMS值 df_size['SMS'] = df_size['diameter_mean'].map(sms_mapping) df_size['SMS_min'] = df_size['diameter_min'].map(sms_mapping) df_size['SMS_max'] = df_size['diameter_max'].map(sms_mapping) # 查看结果 print(df_size)
方法2:多次合并(适合复杂匹配场景)
如果需要保留查找表的其他列,可通过多次merge实现:
# 匹配mean列 df_size = df_size.merge(df_lookup.rename(columns={'diameter':'diameter_mean', 'SMS':'SMS'}), on='diameter_mean', how='left') # 匹配min列 df_size = df_size.merge(df_lookup.rename(columns={'diameter':'diameter_min', 'SMS':'SMS_min'}), on='diameter_min', how='left') # 匹配max列 df_size = df_size.merge(df_lookup.rename(columns={'diameter':'diameter_max', 'SMS':'SMS_max'}), on='diameter_max', how='left')
常见错误原因
merge方法报错ValueError:通常是因为未正确重命名匹配列,或尝试一次性合并多列时列名不匹配、合并逻辑冲突map方法报错KeyError:说明df_size中存在某个直径值不在df_lookup的diameter列中,可通过df_size[~df_size['diameter_mean'].isin(df_lookup['diameter'])]排查缺失值
关于查找键的单调性问题
不需要强单调性。
本次需求是精确匹配,只要df_size中的直径值存在于df_lookup的diameter列中,无论diameter列是否单调,都能通过字典映射或合并成功匹配。只有当使用pd.merge_asof这类区间模糊匹配方法时,才要求查找表的键必须是单调有序的。
内容的提问来源于stack exchange,提问作者Swawa
相关产品推荐
相关产品推荐

