在 2 pandas 数据帧中执行模糊匹配
Perform Fuzzy Matching in 2 pandas dataframe
我有两个行号不同的数据框,其中包含有关玩家的信息。第一个有我需要的所有名字。
df1 = pd.DataFrame({'Player': ["John Sepi", 'Zan Fred', 'Mark Daniel', 'Adam Pop', 'Paul Sepi', 'John Hernandez', 'Price Josiah', 'John Hernandez', 'Adam Pop'],
'Team': ['A', 'C', 'E', 'C', 'B', 'D', 'B', 'A', 'D']})
另一个数据框缺少一些球员,但有一个年龄列。某些情况下玩家的名字差异较小。
df2 = pd.DataFrame({'Player': ["John Sepi", 'Mark A. Daniel', 'John Hernandez', 'Price Josiah', 'John Hernandez', 'Adam Pop'],
'Team': ['A', 'E', 'D', 'B', 'A', 'D'],
'Age': [22, 21, 26, 18, 19, 25]})
等号是不同的人,因此我需要同时匹配球员和球队。我想创建一个新的数据框,其中包含第一个数据框的所有名称以及第二个数据框的相应年龄。如果第二个缺少玩家,请完成具有恒定值的新数据框(例如 XX 年,可以是任何年龄……只是为了说明)。最终数据框:
print(final_df)
Player Team Age
0 John Sepi A 22
1 Zan Fred C XX
2 Mark Daniel E 21
3 Adam Pop C XX
4 Paul Sepi B XX
5 John Hernandez D 26
6 Price Josiah B 18
7 John Hernandez A 19
8 Adam Pop D 25
这是一种方法:
df1 = df1.merge(df2,how='left', on=['Players','Team']).fillna(20)
您可以使用 fuzzywuzzy
库的文本匹配功能与 python 中的 pandas 函数混合使用。
首先,导入以下库:
import pandas as pd
import numpy as np
from fuzzywuzzy import fuzz
from fuzzywuzzy import process
您可以使用 fuzzywuzzy
python 库的文本匹配功能:
#get list of unique teams existing in df1
lst_teams = list(np.unique(np.array(df1['Team'])))
#define arbitrary threshold
thres = 70
#for each team match similar texts
for team in lst_teams:
#iterration on dataframe filtered by team
for index, row in df1.loc[df1['Team']==team].iterrows():
#get list of players in this team
lst_player_per_team = list(np.array(df2.loc[df2['Team']==team]['Player']))
#use of fuzzywuzzy to make text matching
output_ratio = process.extract(row['Player'], lst_player_per_team, scorer=fuzz.token_sort_ratio)
#check if there is players from df2 in this team
if output_ratio !=[]:
#put arbitrary threshold to get most similar text
if output_ratio[0][1]>thres:
df1.loc[index, 'Age'] = df2.loc[(df2['Team']==team)&(df2['Player']==output_ratio[0][0])]['Age'].values[0]
df1 = df1.fillna('XX')
使用此代码和定义为 70 的阈值,您将得到以下结果:
print(df1)
Player Team Age
0 John Sepi A 22
1 Zan Fred C XX
2 Mark Daniel E 21
3 Adam Pop C XX
4 Paul Sepi B XX
5 John Hernandez D 26
6 Price Josiah B 18
7 John Hernandez A 19
8 Adam Pop D 25
可以移动阈值以提高两个数据帧之间文本匹配能力的准确性。
请注意,使用 .iterrows()
时应小心,因为不建议在数据帧上进行迭代。
您可以在此处查看 fuzzywuzzy
文档 https://pypi.org/project/fuzzywuzzy/
我有两个行号不同的数据框,其中包含有关玩家的信息。第一个有我需要的所有名字。
df1 = pd.DataFrame({'Player': ["John Sepi", 'Zan Fred', 'Mark Daniel', 'Adam Pop', 'Paul Sepi', 'John Hernandez', 'Price Josiah', 'John Hernandez', 'Adam Pop'],
'Team': ['A', 'C', 'E', 'C', 'B', 'D', 'B', 'A', 'D']})
另一个数据框缺少一些球员,但有一个年龄列。某些情况下玩家的名字差异较小。
df2 = pd.DataFrame({'Player': ["John Sepi", 'Mark A. Daniel', 'John Hernandez', 'Price Josiah', 'John Hernandez', 'Adam Pop'],
'Team': ['A', 'E', 'D', 'B', 'A', 'D'],
'Age': [22, 21, 26, 18, 19, 25]})
等号是不同的人,因此我需要同时匹配球员和球队。我想创建一个新的数据框,其中包含第一个数据框的所有名称以及第二个数据框的相应年龄。如果第二个缺少玩家,请完成具有恒定值的新数据框(例如 XX 年,可以是任何年龄……只是为了说明)。最终数据框:
print(final_df)
Player Team Age
0 John Sepi A 22
1 Zan Fred C XX
2 Mark Daniel E 21
3 Adam Pop C XX
4 Paul Sepi B XX
5 John Hernandez D 26
6 Price Josiah B 18
7 John Hernandez A 19
8 Adam Pop D 25
这是一种方法:
df1 = df1.merge(df2,how='left', on=['Players','Team']).fillna(20)
您可以使用 fuzzywuzzy
库的文本匹配功能与 python 中的 pandas 函数混合使用。
首先,导入以下库:
import pandas as pd
import numpy as np
from fuzzywuzzy import fuzz
from fuzzywuzzy import process
您可以使用 fuzzywuzzy
python 库的文本匹配功能:
#get list of unique teams existing in df1
lst_teams = list(np.unique(np.array(df1['Team'])))
#define arbitrary threshold
thres = 70
#for each team match similar texts
for team in lst_teams:
#iterration on dataframe filtered by team
for index, row in df1.loc[df1['Team']==team].iterrows():
#get list of players in this team
lst_player_per_team = list(np.array(df2.loc[df2['Team']==team]['Player']))
#use of fuzzywuzzy to make text matching
output_ratio = process.extract(row['Player'], lst_player_per_team, scorer=fuzz.token_sort_ratio)
#check if there is players from df2 in this team
if output_ratio !=[]:
#put arbitrary threshold to get most similar text
if output_ratio[0][1]>thres:
df1.loc[index, 'Age'] = df2.loc[(df2['Team']==team)&(df2['Player']==output_ratio[0][0])]['Age'].values[0]
df1 = df1.fillna('XX')
使用此代码和定义为 70 的阈值,您将得到以下结果:
print(df1)
Player Team Age
0 John Sepi A 22
1 Zan Fred C XX
2 Mark Daniel E 21
3 Adam Pop C XX
4 Paul Sepi B XX
5 John Hernandez D 26
6 Price Josiah B 18
7 John Hernandez A 19
8 Adam Pop D 25
可以移动阈值以提高两个数据帧之间文本匹配能力的准确性。
请注意,使用 .iterrows()
时应小心,因为不建议在数据帧上进行迭代。
您可以在此处查看 fuzzywuzzy
文档 https://pypi.org/project/fuzzywuzzy/