如何在两个大型Pandas DataFrame中用str.contains筛选不匹配街道
检查Pandas DataFrame间字符串匹配并找出不匹配项
我有两个大型Pandas DataFrame:
第一个DataFrame:
import pandas as pd import numpy as np df = pd.DataFrame( [ ("1", "Dixon Street", "Auckland"), ("2", "Deep Creek Road", "Wellington"), ("3", "Lyon St", "Melbourne"), ("4", "Hongmian Street", "Quinxin"), ("5", "Kadawatha Road", "Ganemulla"), ], columns=("ad_no", "street", "city"), )
第二个DataFrame:
dfa = pd.DataFrame( [ ("1 Dixon Street", "Auckland"), ("2 Deep Creek Road", "Wellington"), ("3 Lyon St", "Melbourne"), ("4 Hongmian Street", "Quinxin"), ("5 Federal Street", "Porac City"), ], columns=("address", "city"), )
需求:用str.contains检查df的street字符串是否存在于dfa的address列中,重点找出不匹配的条目(比如Kadawatha Road)。尝试了以下代码但未得到有效结果:
for a in df['street']: dfa[dfa['address'].str.contains(a, case=False)]
问题分析
原代码的问题在于:
- 循环内仅执行筛选操作,但未对结果进行保存或输出,所以看不到任何反馈
- 循环遍历大型DataFrame效率极低,不符合Pandas的向量化操作理念
解决方案
方法1:向量化标记匹配状态并筛选不匹配项
通过apply结合str.contains().any(),为df的每一行标记是否存在匹配,再筛选不匹配的条目:
# 为df添加匹配状态列 df['is_matched'] = df['street'].apply(lambda x: dfa['address'].str.contains(x, case=False).any()) # 筛选出不匹配的条目 unmatched_records = df[~df['is_matched']] print(unmatched_records)
执行后输出:
ad_no street city is_matched 4 5 Kadawatha Road Ganemulla False
方法2:直接生成不匹配列表(无需新增列)
如果不需要保留匹配状态列,可以直接通过列表推导式生成不匹配的street值:
unmatched_streets = [street for street in df['street'] if not dfa['address'].str.contains(street, case=False).any()] print(unmatched_streets)
输出:
['Kadawatha Road']
大数据量优化方案
如果处理超大型DataFrame,可通过正则表达式拼接所有street值,一次性完成匹配提升效率:
# 拼接所有street为正则表达式(用|分隔) street_pattern = '|'.join(df['street'].tolist()) # 找出dfa中匹配任意street的条目 matched_in_dfa = dfa['address'].str.contains(street_pattern, case=False) # 提取dfa中匹配到的street内容,反向筛选df中不匹配的项 matched_streets = dfa.loc[matched_in_dfa, 'address'].str.extract(f'({street_pattern})', expand=False).dropna().unique() unmatched_df = df[~df['street'].isin(matched_streets)]
内容的提问来源于stack exchange,提问作者Totura
相关产品推荐
相关产品推荐

