仅当该值存在时,才通过查找另一个数据框来替换列中的值

Replace a value in a column by vlookup another dataframe only if the value exists

我想根据 (df2.Name1, df2.Name2) 中的映射 table 覆盖我的 df1.Name 值。但是,并非 df1.Name 中的所有值都存在于 df2.Name1

df1:

Name
Alex
Maria 
Marias
Pandas
Coala

df2:

Name1   Name2
Alex    Alexs
Marias  Maria
Coala   Coalas

预期结果:

Name
Alexs
Maria
Maria
Pandas
Coalas

我在网上尝试了几种解决方案,比如使用Map功能。通过在我正在使用 df1.Name = df1.Name.map(Dictionary) 的词典中转换 df2,但这将导致 nan 对于所有不在 df2 中的值,如下所示。

Name
Alexs
Maria
Maria
NAN
Coalas

我不确定如何使用 IF 语句仅替换 df2 中确实存在的那些,并按照 df1 保留其余部分。 我还尝试用 if 语句创建一个函数,但失败了。

我该如何解决这个问题?

Python dict.get() 允许默认参数。因此,如果您构建一个翻译字典,那么如果找不到查找,很容易只返回原始值,如:

代码:

translate = {x: y for x, y in df2[['Name1', 'Name2']].values}
new_names = [translate.get(x, x) for x in df1['Name']]

测试代码:

import pandas as pd

df1 = pd.DataFrame({'Name': ['Alex', 'Maria', 'Marias', 'Pandas', 'Coala']})
df2 = pd.DataFrame({'Name1': ['Alex', 'Marias', 'Coala'],
                    'Name2': ['Alexs', 'Maria', 'Coalas']})

print(df1)
print(df2)

translate = {x: y for x, y in df2[['Name1', 'Name2']].values}
print([translate.get(x, x) for x in df1['Name']])

测试结果:

     Name
0    Alex
1   Maria
2  Marias
3  Pandas
4   Coala

    Name1   Name2
0    Alex   Alexs
1  Marias   Maria
2   Coala  Coalas

['Alexs', 'Maria', 'Maria', 'Pandas', 'Coalas']

您也可以使用replace

df1 = pd.DataFrame({'Name': ['Alex', 'Maria', 'Marias', 'Pandas', 'Coala']})
df2 = pd.DataFrame({'Name1': ['Alex', 'Marias', 'Coala'],
                    'Name2': ['Alexs', 'Maria', 'Coalas']})

# Create the dictionary from df2
d = {"Name": {k:v for k, v in zip(df2["Name1"], df2["Name2"])}}
# Suggestion from Wen to create the dictionary
# d = {"Name": df2.set_index('Name1').Name2.to_dict()}     

df1.replace(d)   # Use df1.replace(d, inplace=True) if you want this in place

    Name
0   Alexs
1   Maria
2   Maria
3   Pandas
4   Coalas

replace 可以带一个字典,你可以在其中指定要替换的列,"Name" 这里,以及你要替换的相应映射在这个特定的列中。

{"Name": {old_1: new_1, old_2: new_2...}}  

-> 替换 "Name" 列中的值,这样 old_1 将替换为 new_1old_2 将替换为 new_2 等等。

感谢 Stephen Rauch 的设置。感谢 Wen 提供了一种干净的创建字典的方法。

让我们使用 Pandas 解决方案 mapcombine_first:

df1['Name'].map(df2.set_index('Name1')['Name2']).combine_first(df1['Name'])

输出:

0     Alexs
1     Maria
2     Maria
3    Pandas
4    Coalas
Name: Name, dtype: object

通过使用replace

df1.Name.replace(df2.set_index('Name1').Name2.to_dict())
Out[437]: 
0     Alexs
1     Maria
2     Maria
3    Pandas
4    Coalas
Name: Name, dtype: object

你也可以使用merge:

In [27]: df1['Name'] = df1.merge(df2.rename(columns={'Name1':'Name'}), how='left') \
                          .ffill(axis=1)['Name2']

In [28]: df1
Out[28]:
     Name
0   Alexs
1   Maria
2   Maria
3  Pandas
4  Coalas