如何在Pandas DataFrame中将Zip+4编码转换为标准Zip编码
Pandas DataFrame中Zip+4编码转标准Zip编码的实现
需求说明
将DataFrame中的Zip+4编码(含01234-5678或012345678格式)转换为5位标准Zip编码,仅保留前5位数字;非数字Zip格式的内容保持原样。
用户尝试记录
- 尝试的错误代码:
df.replace('^(\d{5}-?\d{4})', group(1), regex=True)
- 可行的列表处理代码(希望迁移到DataFrame):
my_input = ['01234-5678', '012345678', '01234', 'A1A 1A1', 'A1A1A1'] expression = re.compile(r'^(\d{5})-?(\d{4})?$') my_output = [] for string in my_input: if m := re.match(expression, string): my_output.append(re.match(expression, string).group(1)) else: my_output.append(string)
解决方案
方法1:str.replace正则替换(最简洁)
直接对目标列使用正则替换,匹配所有符合Zip/ Zip+4的数字格式,保留前5位:
import pandas as pd # 示例DataFrame df = pd.DataFrame({ 'zip_code': ['01234-5678', '012345678', '01234', 'A1A 1A1', 'A1A1A1'] }) # 正则替换:匹配5位数字开头+可选的横杠+4位数字,替换为前5位 df['zip_code'] = df['zip_code'].str.replace(r'^(\d{5})(-?\d{4})?$', r'\1', regex=True)
正则说明:^(\d{5})(-?\d{4})?$精准匹配两种合法格式,非匹配内容(如加拿大邮编)不会被修改。
方法2:str.extract提取+补全
通过提取开头的5位数字,提取失败时保留原内容:
df['zip_code'] = df['zip_code'].str.extract(r'^(\d{5})', expand=False).fillna(df['zip_code'])
逻辑:str.extract仅提取符合条件的前5位数字,提取不到返回NaN,fillna将NaN替换为原字符串。
方法3:沿用列表逻辑的apply方法
直接将列表处理逻辑迁移到DataFrame列,完全匹配用户原有逻辑:
import re expression = re.compile(r'^(\d{5})-?(\d{4})?$') df['zip_code'] = df['zip_code'].apply(lambda x: expression.match(x).group(1) if expression.match(x) else x)
优势:和用户的列表代码逻辑完全一致,便于理解和调试。
内容的提问来源于stack exchange,提问作者Pete
相关产品推荐
相关产品推荐

