【发布时间】:2020-02-22 12:32:49
【问题描述】:
我有两个非常大的表 df1 和 df2(每个表有数百万行),其中包含人员相关数据,每个表都有一个包含人名的列(列名:“姓名”)。同一个人的名字在两张表之间可以写成不同的形式(例如“Jeff McGregor”或“Mr. J McGregor”等),这就是为什么我想用 Python 中的fuzzywuzzy 包应用模糊字符串匹配(这只是比较两个字符串并返回一个相似性度量)。
作为输出(有关所需的输出表,请参见 df3),我想根据 df2 中的条目填写 df1 中的“Match_Flag”和“Match_List”列。对于 df1 中的每个(唯一)人,我想检查 df2 中是否有(模糊字符串)匹配项。如果有字符串,则“Match_Flag”列应包含“yes”,如果没有,则“no”。 “Match_list”列应包含每个名称的匹配列表。如果有一个匹配项,则列表将包含一个条目,如果有例如三个匹配项,列表将包含 3 个匹配项。如果没有匹配,列表应该是空的。
这是数据:
df1
data_df1 = {'ID':[56382, 34732, 12423, 29574, 76532],
'Name':['Tom Hilley', 'Andreas Puthz', 'Jeff McGregor', 'Jack Ebbstein', 'Lisa Norwat'],
'Match_Flag':["", "", "", "", ""],
'Match_List':["", "", "", "", ""]}
df1 = pd.DataFrame(data_df1)
print(df1)
ID Name Match_Flag Match_List
0 56382 Tom Hilley
1 34732 Andreas Puthz
2 12423 Jeff McGregor
3 29574 Jack Ebbstein
4 76532 Lisa Norwat
df2
data_df2 = {'Name':['Tom Hilley', 'Madalina Peter', 'Russel Cross', 'Jenni Pey', 'Kanush Hawks', 'Mr. J McGregor', 'Ebbstein Jack', 'Mr. Jack Ebbstein'],
'Age':[16, 56, 33, 44, 24, 26, 86, 32]}
df2 = pd.DataFrame(data_df2)
print(df2)
Name Age
0 Tom Hilley 16
1 Madalina Peter 56
2 Russel Cross 33
3 Jenni Pey 44
4 Kanush Hawks 24
5 Mr. J McGregor 26
6 Ebbstein Jack 86
7 Mr. Jack Ebbstein 32
df3
data_df3 = {'ID':[56382, 34732, 12423, 29574, 76532],
'Name':['Tom Hilley', 'Andreas Puthz', 'Jeff McGregor', 'Jack Ebbstein', 'Lisa Norwat'],
'Match_Flag':["yes", "no", "yes", "yes", "no"],
'Match_List':[["Tom Hilley"], [], ["Mr. J McGregor"], ["Ebbstein Jack","Mr. Jack Ebbstein"], []]}
df3 = pd.DataFrame(data_df3)
print(df3)
ID Name Match_Flag Match_List
0 56382 Tom Hilley yes [Tom Hilley]
1 34732 Andreas Puthz no []
2 12423 Jeff McGregor yes [Mr. J McGregor]
3 29574 Jack Ebbstein yes [Ebbstein Jack, Mr. Jack Ebbstein]
4 76532 Lisa Norwat no []
我的方法:
# import libraries
import pandas as pd
from fuzzywuzzy import fuzz
# create matching
for i in df1["Name"].unique().tolist():
# initialize matching list
matching_list = []
for j in df2["Name"].unique().tolist():
# create matching score
if fuzz.token_set_ratio(i, j) >= 90:
matching_list.append(j)
# create red flags
if matching_list:
df1.loc[df1['Name'] == i,'Match_Flag'] = 'yes'
df1.loc[df1['Name'] == i,'Match_List'] = matching_list
else:
df1.loc[df1['Name'] == i,'Match_Flag'] = 'no'
df1.loc[df1['Name'] == i,'Match_List'] = ["-"]
我的方法的输出:
line 611, in _setitem_with_indexer
raise ValueError('Must have equal len keys and value '
ValueError: Must have equal len keys and value when setting with an iterable
由于我的方法是 1. 不工作和 2. 对于数百万行来说太慢了,我请你帮助我,并找到一个更有效和工作的方法。 p>
【问题讨论】:
标签: python-3.x pandas list loops fuzzy-comparison