You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从Pandas DataFrame地址列提取城市、州?大数据集特殊行处理咨询

嘿,这个问题我之前帮不少人踩过坑——处理3万条这种大规模地址数据时,单纯靠拆分最后两个元素确实会栽在特殊格式上,毕竟地址的写法实在太灵活了。针对你的情况,我给你几个实用的解决思路:

方案1:用正则匹配标准州标识(快速且易实现)

美国的州通常有两种标准写法:2字母缩写(如CA、NY)或完整州名(如California、New York)。我们可以先定位州的位置,再反向提取前面的城市部分,避开地址里的其他干扰项。

举个Python实现的例子:

import re

# 匹配2字母州缩写或所有州全称的正则
STATE_PATTERN = r'\b(?:[A-Z]{2}|Alabama|Alaska|Arizona|Arkansas|California|Colorado|Connecticut|Delaware|Florida|Georgia|Hawaii|Idaho|Illinois|Indiana|Iowa|Kansas|Kentucky|Louisiana|Maine|Maryland|Massachusetts|Michigan|Minnesota|Mississippi|Missouri|Montana|Nebraska|Nevada|New Hampshire|New Jersey|New Mexico|New York|North Carolina|North Dakota|Ohio|Oklahoma|Oregon|Pennsylvania|Rhode Island|South Carolina|South Dakota|Tennessee|Texas|Utah|Vermont|Virginia|Washington|West Virginia|Wisconsin|Wyoming)\b'

def extract_city_state(address):
    # 查找地址中的州
    state_match = re.search(STATE_PATTERN, address)
    if state_match:
        state = state_match.group()
        # 截取州前面的部分,清理逗号和空格后提取城市
        city_segment = address[:state_match.start()].strip().rstrip(',')
        city = city_segment.split(',')[-1].strip()
        return (city, state)
    # 匹配失败时返回空值,后续可单独处理
    return (None, None)

这个方法对大部分标准美国地址都有效,而且跑3万条数据速度很快。如果是其他国家的地址,只需要替换对应的州/省正则即可。

方案2:用专业地址解析库(应对复杂杂糅地址)

如果你的数据里有大量非标准地址(比如带PO Box、Suite号、多词城市名),正则可能捉襟见肘,这时候专业的地址解析库会更靠谱。比如Python的usaddress(专门处理美国地址),它会自动把地址拆分成「街道、城市、州、邮编」等标准化字段。

示例代码:

import usaddress

def parse_complex_address(address):
    try:
        # 解析地址,返回(内容, 字段类型)的列表
        parsed_parts = usaddress.parse(address)
        # 从解析结果中提取城市和州
        city = next((part[0] for part in parsed_parts if part[1] == 'PlaceName'), None)
        state = next((part[0] for part in parsed_parts if part[1] == 'StateName'), None)
        return (city, state)
    except usaddress.RepeatedLabelError:
        # 处理解析失败的异常,可记录下来后续人工核对
        return (None, None)

使用前需要先安装库:pip install usaddress。这个库的准确率很高,3万条数据跑起来完全没问题,唯一要注意的是极少数极端格式的地址可能解析失败,需要单独处理。

方案3:预处理+规则引擎(针对有规律的特殊数据)

如果你的特殊地址(比如你提到的第3、4行)有固定规律(比如带特定前缀、多逗号分隔),可以先做预处理清理冗余内容,再结合规则判断城市和州:

import re

# 预定义州全称集合,用于判断
STATE_FULL_NAMES = {'Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorado', 'Connecticut', 'Delaware', 'Florida', 'Georgia', 'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana', 'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire', 'New Jersey', 'New Mexico', 'New York', 'North Carolina', 'North Dakota', 'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island', 'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont', 'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming'}

def clean_address(address):
    # 移除常见冗余前缀,比如PO Box、Suite号
    address = re.sub(r'PO Box \d+, ', '', address)
    address = re.sub(r'Suite \d+, ', '', address)
    return address.strip()

def extract_with_rules(address):
    cleaned_addr = clean_address(address)
    # 按逗号拆分地址,过滤空字符串
    addr_parts = [part.strip() for part in cleaned_addr.split(',') if part.strip()]
    
    if len(addr_parts) >= 2:
        # 先检查最后一个部分是否是州
        candidate_state = addr_parts[-1]
        if re.match(r'[A-Z]{2}$', candidate_state) or candidate_state in STATE_FULL_NAMES:
            return (addr_parts[-2], candidate_state)
        # 如果最后一个是邮编,那前一个大概率是州
        elif re.match(r'\d{5}', candidate_state) and len(addr_parts) >=3:
            return (addr_parts[-3], addr_parts[-2])
    return (None, None)

这种方法适合你已经摸清楚特殊数据的规律时使用,可以和前面的方法结合,进一步提升准确率。

最后小建议

  1. 先拿一小部分特殊数据测试这几个方法,选准确率最高的作为主方案
  2. 把所有解析失败的记录单独导出,人工处理或者补充规则——3万条数据里特殊数据占比应该不会太高,人工成本可控
  3. 如果是跨国地址,换对应国家的解析库(比如英国用ukaddress)即可

内容的提问来源于stack exchange,提问作者Aruna J

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:21:05