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

使用pandas按顺序匹配多列字符串填充State州列的实现方案

解决方案

你之前代码出现覆盖问题的核心原因是:赋值时没有过滤State列已经存在有效值的行,直接对所有匹配到的行统一赋值,才会把原有合法值覆盖。

实现逻辑

严格按照State > Location > Origin的优先级,仅对State列为空的行执行后续匹配填充,从高优先级列取到有效值后就不再处理该行,避免覆盖:

  1. 先清洗原始State列,仅保留在给定州名列表内的有效值,无效值统一转为空值
  2. 对State为空的行,从Location列提取匹配的州名填充
  3. 对仍为空的行,最后从Origin列提取匹配的州名填充

代码实现

方法1:通用逻辑(易理解,适合中小数据集)

import pandas as pd
import numpy as np

# 测试数据和州名列表可直接复用你提供的版本
df = pd.DataFrame({'State': [np.nan, np.nan, np.nan, np.nan, 
                             np.nan, 'California', np.nan, np.nan],
                   'Location': ['Seattle, Washington', 'California', 'INPUT ERROR', 'Portland, Oregon',
                              'INPUT ERROR', 'San Bernardino', 'ERROR', 'Seattle'],
                   'Origin': ['Portland, Oregon', 'San Francisco', 'RANDOM ERROR', 'INPUT ERROR',
                                   'Las Vegas, Nevada', 'Nevada, Barstow', 'Portland', 'Washington, Tacoma']})

states = ['Alaska', 'Arizona', 'California', 
          'Colorado', 'Hawaii', 'Idaho', 
          'Montana', 'Nevada', 'New Mexico', 
          'Oregon', 'Utah', 'Washington',
          'Wyoming']

# 定义提取州名的辅助函数
def extract_valid_state(text, state_list):
    if pd.isna(text):
        return np.nan
    # 按逗号拆分字符串后逐个匹配,返回第一个命中的州名
    text_parts = [part.strip() for part in str(text).split(',')]
    for part in text_parts:
        if part in state_list:
            return part
    return np.nan

# 1. 清洗原State列,保留合法值
df['State'] = df['State'].apply(lambda x: x if x in states else np.nan)

# 2. 仅填充State为空的行:从Location提取
empty_mask = df['State'].isna()
df.loc[empty_mask, 'State'] = df.loc[empty_mask, 'Location'].apply(lambda x: extract_valid_state(x, states))

# 3. 填充剩余空行:从Origin提取
empty_mask = df['State'].isna()
df.loc[empty_mask, 'State'] = df.loc[empty_mask, 'Origin'].apply(lambda x: extract_valid_state(x, states))

运行后最终State列结果:

索引State
0Washington
1California
2Oregon
3Oregon
4Nevada
5California
6Oregon
7Washington

可以看到索引5行原有的California没有被覆盖,完全符合要求。

方法2:向量化操作(性能更高,适合百万级以上大数据集)

用正则匹配+combine_first按优先级取第一个非空值,避免apply循环的性能损耗:

# 生成州名正则匹配模式
state_reg = '|'.join(states)

# 分别从Location、Origin列提取第一个匹配的州名
df['loc_state'] = df['Location'].str.extract(f'({state_reg})', expand=False)
df['origin_state'] = df['Origin'].str.extract(f'({state_reg})', expand=False)

# 按优先级合并:原State >  Location提取值 > Origin提取值
df['State'] = df['State'].combine_first(df['loc_state']).combine_first(df['origin_state'])

# 可选:删除临时生成的辅助列
df.drop(['loc_state', 'origin_state'], axis=1, inplace=True)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 20:39:04