基于Pandas实现两列VLOOKUP并查找缺失值
没问题,我来帮你搞定这个需求!在pandas里实现两列匹配的VLOOKUP效果,再找出匹配后的缺失值其实很直观,我给你一步步拆解:
1. 先搞懂对应关系:Excel VLOOKUP → Pandas Merge
Excel里的多列VLOOKUP,对应到pandas里就是多键左连接(left merge)——它会保留主表的所有行,只把参考表里匹配上的值拉过来,没匹配到的位置就会自动填充NaN,这正好符合我们的需求。
2. 代码实战示例
先假设我们有两个核心DataFrame:
- 主表
main_df:包含需要用来匹配的两列(比如user_id和order_date),还有其他业务数据 - 参考表
lookup_df:包含相同的匹配列,以及我们要“VLOOKUP”过来的目标列(比如order_amount)
先构造一组示例数据方便演示:
import pandas as pd # 主表:包含所有需要匹配的行 main_df = pd.DataFrame({ 'user_id': [101, 102, 103, 104, 105], 'order_date': ['2024-01-01', '2024-01-02', '2024-01-03', '2024-01-04', '2024-01-05'], 'product': ['A', 'B', 'C', 'D', 'E'] }) # 参考表:只有部分匹配项(104、105的order_date没有对应数据) lookup_df = pd.DataFrame({ 'user_id': [101, 102, 103], 'order_date': ['2024-01-01', '2024-01-02', '2024-01-03'], 'order_amount': [100, 200, 300] })
接下来执行“多列VLOOKUP”操作:
# 基于两列做左连接,完全模拟VLOOKUP逻辑 merged_df = pd.merge(main_df, lookup_df, on=['user_id', 'order_date'], how='left') print(merged_df)
运行后输出会是:
user_id order_date product order_amount 0 101 2024-01-01 A 100.0 1 102 2024-01-02 B 200.0 2 103 2024-01-03 C 300.0 3 104 2024-01-04 D NaN 4 105 2024-01-05 E NaN
你能看到,没匹配上的行(104、105)的order_amount列就是NaN,这就是我们要找的缺失值。
3. 精准筛选匹配失败的行
现在我们要把这些缺失值对应的行单独拎出来,有两种实用方式:
方式1:直接筛选NaN行
最直接的方式就是用isna()判断目标列的缺失值:
# 筛选出order_amount为NaN的行(也就是匹配失败的行) missing_matches = merged_df[merged_df['order_amount'].isna()] print(missing_matches)
输出结果就是所有匹配失败的记录:
user_id order_date product order_amount 3 104 2024-01-04 D NaN 4 105 2024-01-05 E NaN
方式2:用indicator参数看匹配状态(更直观)
如果想明确知道每一行的匹配类型(是主表独有、参考表独有还是两者都有),可以在merge时加上indicator=True:
# 带匹配状态的左连接 merged_df_with_status = pd.merge( main_df, lookup_df, on=['user_id', 'order_date'], how='left', indicator=True ) # 筛选主表独有的行(也就是参考表里找不到匹配的行) missing_matches = merged_df_with_status[merged_df_with_status['_merge'] == 'left_only'] print(missing_matches)
这种方式能让你更清晰地确认这些行确实是主表里存在但参考表没有匹配项的。
额外小提示
- 如果两个表里的匹配列名字不一样,比如主表是
user_id和order_date,参考表是cust_id和trans_date,可以用left_on=['user_id', 'order_date'], right_on=['cust_id', 'trans_date']来分别指定 - 如果需要填充缺失值(比如用0或者默认值),可以用
merged_df['order_amount'].fillna(0, inplace=True)来处理
内容的提问来源于stack exchange,提问作者bala chandar
相关产品推荐
相关产品推荐

