仅当该值存在时,才通过查找另一个数据框来替换列中的值
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_1
。 old_2
将替换为 new_2
等等。
感谢 Stephen Rauch 的设置。感谢 Wen 提供了一种干净的创建字典的方法。
让我们使用 Pandas 解决方案 map
和 combine_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
我想根据 (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_1
。 old_2
将替换为 new_2
等等。
感谢 Stephen Rauch 的设置。感谢 Wen 提供了一种干净的创建字典的方法。
让我们使用 Pandas 解决方案 map
和 combine_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