Python 比较数据帧内容并在匹配时替换?

Python Compare dataframe contents and replace if match?

我正在开发一个小程序作为 python 的练习,需要一些帮助来尝试比较数据框中的两列并将其中一列的内容替换为另一列。我可以看到我的结果,因为我已将数据框转换为 excel。

无论如何,我想比较两列 LocationAbbrev 基于每个的前三个字母,然后替换为缩写。因此,Abbrev 列中的 LON 应与 London 中的前三个字母进行比较。 Abbrev栏只给出一个缩写实例

所以我开始:

Team         Location    GameDay   Abbrev
Arsenal      London      2/14      LON
Liverpool    Liverpool   2/14      LIV
Manchester   Manchester  2/16      MAN
Arsenal      London      2/23      NEW
Newcastle    Manchester  2/16      LEE

我想得到这个输出:

Team        Location  GameDay   Abbrev
Arsenal     LON       2/14      LON
Liverpool   LIV       2/14      LIV
Manchester  MAN       2/16      MAN
Arsenal     LON       2/23      NEW
Newcastle   MAN       2/16      LEE

但是,现在无论匹配如何,我都只能完全替换列。

Team        Location    GameDay   Abbrev
Arsenal     LON         2/14      LON
Liverpool   LIV         2/14      LIV
Manchester  MAN         2/16      MAN
Arsenal     NEW         2/23      NEW
Newcastle   LEE         2/16      LEE

这是我的代码。

df['Location'] = df.apply(lambda row: row['Abbrev'] 
                          if row['Location'][:3].upper() != row['Abbrev'] 
                          else row['Abbrev'],axis=1)

我想帮助找出我的代码有什么问题。

您需要检查 row['Location'][:3] 是否在缩写中:

import pandas as pd

data = [['Arsenal', 'London', '2/14', 'LON'],
        ['Liverpool', 'Liverpool', '2/14', 'LIV'],
        ['Manchester', 'Manchester', '2/16', 'MAN'],
        ['Arsenal', 'London', '2/23', 'NEW'],
        ['Newcastle', 'Manchester', '2/16', 'LEE']]

df = pd.DataFrame(data=data, columns=['Team', 'Location', 'GameDay', 'Abbrev'])

abbreviations = set(df.Abbrev.values)
df['Location'] = df.apply(lambda row: row['Location'][:3].upper() if row['Location'][:3].upper() in abbreviations else row['Abbrev'], axis=1)

print(df)

输出

         Team Location GameDay Abbrev
0     Arsenal      LON    2/14    LON
1   Liverpool      LIV    2/14    LIV
2  Manchester      MAN    2/16    MAN
3     Arsenal      LON    2/23    NEW
4   Newcastle      MAN    2/16    LEE

更新

如果您更喜欢单线:

df['Location'] = df.apply(lambda row: row['Location'][:3].upper() if row['Location'][:3].upper() in df.Abbrev.values else row['Abbrev'], axis=1)

不确定我是否 100% 理解,但仅根据您可以执行的示例数据:

df['Location'] = df['Location'].str[:3].str.upper()

但听起来您希望该位置只填充来自 Abbrev 的值,您没有说如果值不在 Abbrev 中您希望的行为是什么, 所以我假设 NaN:

# Map to first 3 letters
df['Location'] = df['Location'].str[:3].str.upper()
# null out values not in Abbrev
df.loc[~df['Location'].isin(df['Abbrev']), 'Location'] = np.nan