如何处理pandas列内不规则空格 保障str.split()正确拆分字段
问题背景
有 pandas DataFrame 包含location列,列内容为美国地址信息,样例如下:
该列空格数量不统一:部分单元格存在3-5个不等的空格,标准格式仅需要2个空格,分别作为「城市-州」「州-邮政编码」的分隔。直接使用str.split()按空格拆分、或者全局替换空格为其他分隔符,都会因为城市名内部自带空格导致拆分片段长度不统一,无法得到预期的「城市/州/邮编」三段结构。
需求是仅替换城市名称内部的空格为连字符,保留两段分隔用空格,保证后续拆分正常。
实现方案
这类地址字段不需要纠结空格数量,利用美国地址尾部两段格式固定的特征(州为2位大写字母缩写、邮编为数字开头的规则串),直接从后往前匹配即可,鲁棒性远高于正向计数空格的方案。
最优方案:正则直接拆分(无需提前替换空格)
直接用str.extract()通过正则捕获组一次性拆分出三列,跳过替换空格的步骤,不管城市名带多少空格、分隔位有多少个空格都能精准匹配:
import pandas as pd # 一次性拆分出城市、州、邮编三列 df[['city', 'state', 'zip_code']] = df['location'].str.extract( r'^(.*?)\s+([A-Z]{2})\s+(\d[\d-]*)$' )
正则规则说明:
^:匹配字符串起始位置(.*?):非贪婪匹配所有字符直到后续规则命中,对应城市名,兼容城市名内部带任意数量空格的情况\s+:匹配城市与州之间任意数量的空格(1个/3个/5个空格都可识别)([A-Z]{2}):严格匹配2位大写字母的州缩写\s+:匹配州与邮编之间任意数量的空格(\d[\d-]*)$:匹配字符串末尾、数字开头的邮编,兼容5位基础邮编、带扩展位的12345-6789格式邮编
适配需求方案:先替换城市内空格为连字符再拆分
如果必须要先把location列处理成仅含2个分隔空格的格式、再走str.split()流程,可以在提取三段内容后单独处理城市名的空格,再拼接为标准格式:
import re def clean_location(text): # 按固定规则拆分三段 match_res = re.match(r'^(.*?)\s+([A-Z]{2})\s+(\d[\d-]*)$', text.strip()) city, state, zipc = match_res.groups() # 仅替换城市内部的空格为连字符 city = city.replace(' ', '-') # 拼接为标准单空格分隔格式 return f"{city} {state} {zipc}" df['location_clean'] = df['location'].apply(clean_location) # 此时按单个空格拆分百分百得到3段 df[['city', 'state', 'zip_code']] = df['location_clean'].str.split(' ', expand=True)
注意:不要使用正向数空格位置、全局替换空格的逻辑,美国存在大量多空格城市名(如New York、Salt Lake City、Las Vegas),正向规则很容易出现拆分错位,基于尾部固定格式反向匹配是这类地址处理的通用无坑方案。
内容的提问来源于stack exchange,提问作者ela rednax
相关产品推荐
相关产品推荐

