如何将ZIP码前4位匹配到范围并关联对应省份信息?
问题描述
我有如下两个DataFrame:
df1
| ZIP code | Other columns |
|---|---|
| 1011AA | ... |
| 1011AA | ... |
| 2316XH | ... |
| 5815NE | ... |
df2
| starting value ZIP code range | last value ZIP code range | Province |
|---|---|---|
| 1000 | 1200 | North-Holland |
| 1201 | 1500 | South-Holland |
| 1501 | 1570 | North-Holland |
| 1571 | 1600 | Den Haag |
需要完成以下操作:
- 提取
df1["ZIP code"]的前4位数字; - 检查该4位数字是否落在
df2中任意一组区间范围内; - 匹配成功后,将对应的
df2["Province"]值添加到df1新列中。
优先想用map方法实现,比如df1["New column"] = df1["ZIP code"].str[:4].map(... ? ...),如果map不合适也可以推荐更优方案。
解决方案
首先要统一数据类型:把df2的区间列转成整数,同时将df1提取的前四位字符串也转成整数,才能进行数值区间匹配。
方法1:用map结合自定义函数(适合小数据量)
逻辑直观,适合数据量不大的场景:
import pandas as pd # 转换df2区间列的数据类型 df2['starting value ZIP code range'] = df2['starting value ZIP code range'].astype(int) df2['last value ZIP code range'] = df2['last value ZIP code range'].astype(int) # 定义匹配省份的函数 def match_province(zip_prefix): zip_num = int(zip_prefix) # 遍历df2找对应区间 for _, row in df2.iterrows(): if row['starting value ZIP code range'] <= zip_num <= row['last value ZIP code range']: return row['Province'] # 无匹配返回空值 return pd.NA # 应用map方法 df1['New column'] = df1['ZIP code'].str[:4].map(match_province)
方法2:用merge_asof(高效推荐,适合大数据量)
如果数据量较大,逐行遍历效率很低,推荐用pandas专门的区间匹配工具merge_asof:
import pandas as pd # 处理df1:提取前四位并转成整数 df1['zip_prefix'] = df1['ZIP code'].str[:4].astype(int) # 处理df2:重命名列并转换类型 df2_processed = df2.rename(columns={ 'starting value ZIP code range': 'start_zip', 'last value ZIP code range': 'end_zip' }).astype({'start_zip': int, 'end_zip': int}) # merge_asof要求右表必须按匹配列排序 df2_processed = df2_processed.sort_values('start_zip') # 执行区间匹配 result = pd.merge_asof( df1.sort_values('zip_prefix'), # 左表也要按匹配列排序 df2_processed, left_on='zip_prefix', right_on='start_zip', direction='backward' ) # 过滤掉不在区间内的匹配结果 result = result[result['zip_prefix'] <= result['end_zip']] # 将匹配结果合并回原df1(保留原顺序) df1 = df1.merge(result[['ZIP code', 'Province']], on='ZIP code', how='left').rename(columns={'Province': 'New column'})
结果示例
处理后df1的结果如下(注:原示例中的Haarlem、Utrecht未在给出的df2区间中对应,实际会返回空值,需补充对应区间数据):
| ZIP code | Other columns | New column |
|---|---|---|
| 1011AA | ... | North-Holland |
| 1011AA | ... | North-Holland |
| 2316XH | ... | NaN |
| 5815NE | ... | NaN |
内容的提问来源于stack exchange,提问作者Xtiaan
相关产品推荐
相关产品推荐

