能否用Python程序化清理此类表格数据?
处理混乱美国地址数据的Python方案
针对你这种格式混乱的美国地址表格,单纯用split()或简单字符串匹配容易踩坑,结合正则表达式和地址规则的方案更高效。下面直接给实用方法和需要掌握的工具:
核心工具与必学函数
- pandas库:处理表格的核心,重点学这些字符串方法:
str.extract():用正则提取指定内容str.replace():批量替换冗余字符str.strip():清除首尾空格fillna():填充空值
- re模块(正则表达式):利用美国地址的固定格式(州缩写为2位大写字母、邮编为5位数字)精准提取,比手动拆分靠谱得多。
对你两个思路的评价
- 搜索州缩写的思路:可行,但要结合正则避免误匹配(比如公司名里的类似缩写),搭配邮编提取一起用,准确率会更高。
- 按逗号split的思路:局限性太大,处理不了无逗号的地址(比如
Grand Rapids MI 49501),不推荐。
最优处理流程(附代码示例)
以你的示例数据为例,步骤如下:
1. 初始化数据与预处理
先把表格读入pandas,统一替换空标记--为标准空值:
import pandas as pd import re # 示例数据 data = { 'Place': ['Burger King Hartford, CT', "McDonald's", "Arby's", "Taco Bell", "Jimmy Johns"], 'Address': ['123 Apple St W', '5 Big Mac dr', '--', '--', '--'], 'City': ['--', 'New York, NY 10001', 'Sturgis, KY', 'Grand Rapids MI 49501', 'Fort Wayne, IN. 46774'], 'State': ['--', '--', '--', '--', '--'], 'Zip': ['--', '--', '--', '--', '--'] } df = pd.DataFrame(data) df.replace('--', pd.NA, inplace=True)
2. 定义提取函数
用正则精准提取州缩写和邮编:
# 提取州缩写:匹配前后带逗号/空格的2位大写字母,兼容带点号的情况(比如IN.) def extract_state(text): if pd.isna(text): return pd.NA match = re.search(r'(?:,|\s)([A-Z]{2})(?:\.?\s|\.|$)', text) return match.group(1) if match else pd.NA # 提取5位邮编,支持拓展到9位(改成r'\b(\d{5}(?:-\d{4})?)\b'即可) def extract_zip(text): if pd.isna(text): return pd.NA match = re.search(r'\b(\d{5})\b', text) return match.group(1) if match else pd.NA
3. 批量提取并填充列
从Place、City列中提取州和邮编,填充到对应列:
# 先从Place列提取 df['State'] = df['State'].fillna(df['Place'].apply(extract_state)) df['Zip'] = df['Zip'].fillna(df['Place'].apply(extract_zip)) # 再从City列补充提取(处理Place列没有的情况) df['State'] = df['State'].fillna(df['City'].apply(extract_state)) df['Zip'] = df['Zip'].fillna(df['City'].apply(extract_zip))
4. 清理原列冗余内容
把原列中混杂的州、邮编信息删掉:
# 清理Place列中的州信息 df['Place'] = df['Place'].str.replace(r',?\s*[A-Z]{2}\b\.?', '', regex=True).str.strip() # 清理City列中的州和邮编信息 df['City'] = df['City'].str.replace(r',?\s*[A-Z]{2}\b\.?\s*\d{5}?', '', regex=True).str.strip()
处理后的数据会变成:
| Place | Address | City | State | Zip |
|---|---|---|---|---|
| Burger King Hartford | 123 Apple St W | CT | ||
| McDonald's | 5 Big Mac dr | New York | NY | 10001 |
| Arby's | Sturgis | KY | ||
| Taco Bell | Grand Rapids | MI | 49501 | |
| Jimmy Johns | Fort Wayne | IN | 46774 |
进阶方案:专业地址解析库
如果数据复杂度更高(比如包含街道、公寓号等),可以用usaddress库专门解析美国地址,安装后直接调用:
import usaddress def parse_full_address(text): if pd.isna(text): return {} try: parsed = usaddress.parse(text) return {key: ' '.join(val for val, key in parsed) for key in ['PlaceName', 'StateName', 'ZipCode']} except: return {} # 解析City列的地址并拆分 city_parsed = df['City'].apply(parse_full_address).apply(pd.Series) df['City'] = df['City'].fillna(city_parsed['PlaceName']) df['State'] = df['State'].fillna(city_parsed['StateName']) df['Zip'] = df['Zip'].fillna(city_parsed['ZipCode'])
内容的提问来源于stack exchange,提问作者Ooch
相关产品推荐
相关产品推荐

