根据数据框中的特定列检测和附加重复项的最快方法
Fastest way to detect and append duplicates base on specific column in dataframe
以下是示例数据:
name age gender school
Michael Z 21 Male Lasalle
Lisa M 22 Female Ateneo
James T 21 Male UP
Michael Z. 23 Male TUP
这是我需要的预期输出:
name age gender similar name on_lasalle on_ateneo on_up on_tup
Michael Z 21 Male Michael Z. True False False True
Lisa M 22 Female False True False False
James T 21 Male False False True False
我一直在尝试在我的 python 脚本中使用 fuzzywuzzy
。我得到的数据来自 bigquery
,然后我将其转换为 dataframe
以清理一些东西。之后,我将 dataframe
转换为 list of dictionaries
.
请注意上面的数据,其中 TUP 的 Michael Z. 被附加到 Lasalle 学校的 Michael Z,因为他们有相似的名字,相似率为 100% fuzz.token_set_ratio
我想要的是根据名称获取所有相似的行并将其附加到我们正在查看的当前字典(包括他们的学校)。
这是根据名称获取相似行的代码和循环:
data_dict_list = data_df.to_dict('records')
for x in range(0, len(data_dict_list)):
for y in range(x, len(data_dict_list)):
if not data_dict_list[x]['is_duplicate']:
similarity = fuzz.token_set_ratiod(data_dict_list[x]['name'], data_dict_list[y]['name'])
if similarity >= 90:
data_dict_list[x]['similar_names'].update('similar_name': data_dict_list[y]['name'])
...
data_dict_list[x]['is_duplicate'] = True
这个脚本的运行速度非常慢,有时我会得到 100,000 多个数据!!!所以它将遍历所有这些数据。
我怎样才能加快这个过程?
建议 pandas
非常感谢,因为我很难弄清楚如何在其中循环数据。
作为第一步,您只需将 fuzzywuzzy
的导入替换为 rapidfuzz
:
from rapidfuzz import fuzz
这应该已经大大提高了性能。您可以通过以下方式比较 rapidfuzz 中的完整字符串列表来进一步提高性能:
>> import pandas as pd
>> from rapidfuzz import process, fuzz
>> df = pd.DataFrame(data={'name': ['test', 'tests']})
>> process.cdist(df['name'], df['name'], scorer=fuzz.token_set_ratio, score_cutoff=90)
array([[100, 0],
[ 0, 100]], dtype=uint8)
其中 returns 结果矩阵,其中得分低于 90 的所有元素都设置为 0。对于大型数据集,您可以使用 workers
参数启用多线程:
process.cdist(df['name'], df['name'], workers=-1, scorer=fuzz.token_set_ratio, score_cutoff=90)
以下是示例数据:
name age gender school
Michael Z 21 Male Lasalle
Lisa M 22 Female Ateneo
James T 21 Male UP
Michael Z. 23 Male TUP
这是我需要的预期输出:
name age gender similar name on_lasalle on_ateneo on_up on_tup
Michael Z 21 Male Michael Z. True False False True
Lisa M 22 Female False True False False
James T 21 Male False False True False
我一直在尝试在我的 python 脚本中使用 fuzzywuzzy
。我得到的数据来自 bigquery
,然后我将其转换为 dataframe
以清理一些东西。之后,我将 dataframe
转换为 list of dictionaries
.
请注意上面的数据,其中 TUP 的 Michael Z. 被附加到 Lasalle 学校的 Michael Z,因为他们有相似的名字,相似率为 100% fuzz.token_set_ratio
我想要的是根据名称获取所有相似的行并将其附加到我们正在查看的当前字典(包括他们的学校)。
这是根据名称获取相似行的代码和循环:
data_dict_list = data_df.to_dict('records')
for x in range(0, len(data_dict_list)):
for y in range(x, len(data_dict_list)):
if not data_dict_list[x]['is_duplicate']:
similarity = fuzz.token_set_ratiod(data_dict_list[x]['name'], data_dict_list[y]['name'])
if similarity >= 90:
data_dict_list[x]['similar_names'].update('similar_name': data_dict_list[y]['name'])
...
data_dict_list[x]['is_duplicate'] = True
这个脚本的运行速度非常慢,有时我会得到 100,000 多个数据!!!所以它将遍历所有这些数据。
我怎样才能加快这个过程?
建议 pandas
非常感谢,因为我很难弄清楚如何在其中循环数据。
作为第一步,您只需将 fuzzywuzzy
的导入替换为 rapidfuzz
:
from rapidfuzz import fuzz
这应该已经大大提高了性能。您可以通过以下方式比较 rapidfuzz 中的完整字符串列表来进一步提高性能:
>> import pandas as pd
>> from rapidfuzz import process, fuzz
>> df = pd.DataFrame(data={'name': ['test', 'tests']})
>> process.cdist(df['name'], df['name'], scorer=fuzz.token_set_ratio, score_cutoff=90)
array([[100, 0],
[ 0, 100]], dtype=uint8)
其中 returns 结果矩阵,其中得分低于 90 的所有元素都设置为 0。对于大型数据集,您可以使用 workers
参数启用多线程:
process.cdist(df['name'], df['name'], workers=-1, scorer=fuzz.token_set_ratio, score_cutoff=90)