使用 pandas 顺序计算多列上的字符串

Use pandas to sequentially evaluate strings on multiple columns

我有一个很大的位置数据集,其中有很多输入错误(电话营销)。我需要创建一个列来清楚地标识一个状态,并且该信息可能出现在不同的列中。 以下玩具数据说明了这个问题。

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']

我需要以某种方式用 'State' 列或 'Location' 或 [=34= 中最先出现的值填充 'State' 列(真的没关系!) ] 列。我的想法是创建一个状态列表并比较每一行和每一列以找到匹配项并将第一个匹配项作为 'State' 列中的值。

为了实现这一点,我认为我需要首先将 'Location' 和 'Origin' 中的字符串拆分为单个字符串,然后按顺序比较(状态>位置>来源)直到找到有效状态...卡在那里。

# Split string and create new columns for comparison
df[['Location1','Location2']] = df['Location'].str.split(', ', n=1, expand=True)
df[['origin1','origin2']] = df['Origin'].str.split(', ', n=1, expand=True)

结果如下table

这就是我正在尝试的:

# Go through each column one by one...
df.loc[df['Location2'].isin(states), 'State'] = df['Location2']
df.loc[df['origin1'].isin(states), 'State'] = df['origin1']
# Etc...

请注意,在这种情况下,条目索引 5 从加利福尼亚(已在 'State' col)更改为内华达(有效州),因为评估中没有顺序。

总结一下,我需要评估 State、Location 和 Origin 列字符串,按顺序生成一个有效的状态列表,第一个有效的字符串将作为结果放入 'State' 列。

谢谢!

快速简单的解决方案。加入所有字段,使用包含所有州名的正则表达式搜索第一个州名:

pattern = '|'.join(states)
(df.fillna('')
    .apply(' '.join, axis=1)
    .str.findall(pattern)
    .str[0]
 )

输出:


0    Washington
1    California
2           NaN
3        Oregon
4        Nevada
5    California
6           NaN
7    Washington

尝试在 LocationOrigin 列中使用 pat 提取状态。每次,使用 combine_first.

更新 State 列中找到的状态的 nan 值
pat = fr"({'|'.join(states)})"

df['State'] = \
    df['State'].combine_first(df['Location'].str.extract(pat, expand=False)) \
               .combine_first(df['Origin'].str.extract(pat, expand=False))

正则表达式查找

>>> df
        State             Location              Origin
0  Washington  Seattle, Washington    Portland, Oregon
1  California           California       San Francisco
2         NaN          INPUT ERROR        RANDOM ERROR
3      Oregon     Portland, Oregon         INPUT ERROR
4      Nevada          INPUT ERROR   Las Vegas, Nevada
5  California       San Bernardino     Nevada, Barstow
6         NaN                ERROR            Portland
7  Washington              Seattle  Washington, Tacoma

>>> pat
'(Alaska|Arizona|California|Colorado|Hawaii|Idaho|Montana|Nevada|New Mexico|Oregon|Utah|Washington|Wyoming)'