gpt4 book ai didi

python - Pandas 中的序列相似度匹配

转载 作者:行者123 更新时间:2023-12-02 02:23:14 25 4
gpt4 key购买 nike

我尝试在 SO 中搜索答案,但没有找到任何帮助。

这就是我正在尝试做的事情:
我有一个数据框(这是一个小例子):

 df = pd.DataFrame([[1, 5, 'AADDEEEEIILMNORRTU'], [2, 5, 'AACEEEEGMMNNTT'], [3, 5, 'AAACCCCEFHIILMNNOPRRRSSTTUUY'], [4, 5, 'DEEEGINOOPRRSTY'], [5, 5, 'AACCDEEHHIIKMNNNNTTW'], [6, 5, 'ACEEHHIKMMNSSTUV'], [7, 5, 'ACELMNOOPPRRTU'], [8, 5, 'BIT'], [9, 5, 'APR'], [10, 5, 'CDEEEGHILLLNOOST'], [11, 5, 'ACCMNO'], [12, 5, 'AIK'], [13, 5, 'CCHHLLOORSSSTTUZ'], [14, 5, 'ANNOSXY'], [15, 5, 'AABBCEEEEHIILMNNOPRRRSSTUUVY']],columns=['PartnerId','CountryId','Name'])

我的目标是找到Name至少在一定比率范围内相似的PartnerId
此外,我只想比较具有相同 CountryIdPartnerId。匹配的 PartnerId 应附加到列表中,并最终写入数据帧中的新列中。

这是我的尝试:

itemDict = {item[0]: {'CountryId': item[1], 'Name': item[2]} for item in df.values}

from difflib import SequenceMatcher
def similar(a, b):
return SequenceMatcher(None, a, b).ratio()

def calculate_similarity(x,itemDict):
own_name = x['Name']
country_id = x['CountryId']
matching_ids = []
for k, v in itemDict.items():

if k != x['PartnerId']:
if v['CountryId'] == country_id:

ratio = similar(own_name,v['Name'])


if ratio > 0.7:

matching_ids.append(k)
return matching_ids

df['Similar_IDs'] = df.apply(lambda x: calculate_similarity(x,itemDict),axis=1)
print(df)

输出为:

    PartnerId  CountryId                          Name Similar_IDs
0 1 5 AADDEEEEIILMNORRTU []
1 2 5 AACEEEEGMMNNTT []
2 3 5 AAACCCCEFHIILMNNOPRRRSSTTUUY [15]
3 4 5 DEEEGINOOPRRSTY [10]
4 5 5 AACCDEEHHIIKMNNNNTTW []
5 6 5 ACEEHHIKMMNSSTUV []
6 7 5 ACELMNOOPPRRTU []
7 8 5 BIT []
8 9 5 APR []
9 10 5 CDEEEGHILLLNOOST [4]
10 11 5 ACCMNO []
11 12 5 AIK []
12 13 5 CCHHLLOORSSSTTUZ []
13 14 5 ANNOSXY []
14 15 5 AABBCEEEEHIILMNNOPRRRSSTUUVY [3]

我现在的问题是:
1.) 有没有更有效的计算方法?我现在有大约 20,000 行,并且在不久的将来还会有更多。
2.)是否可以“摆脱”itemDict并直接从数据帧中进行操作?
3.) 使用另一种距离测量可能更好吗?

非常感谢您的帮助!

最佳答案

您可以使用模块difflib。首先,您需要通过使用外连接将表连接到自身来生成所有字符串的笛卡尔积:

cols = ['Name', 'CountryId', 'PartnerId']
df = df[cols].merge(df[cols], on='CountryId', how='outer')
df = df.query('PartnerId_x != PartnerId_y')

在下一步中,您可以应用此 answer 中的函数。并过滤掉所有匹配项:

def match(x):
return SequenceMatcher(None, x[0], x[1]).ratio()

match = df.apply(match, axis=1) > 0.7
df.loc[match, ['PartnerId_x', 'Name_x', 'PartnerId_y']]

输出:

     PartnerId_x                        Name_x  PartnerId_y
44 3 AAACCCCEFHIILMNNOPRRRSSTTUUY 15
54 4 DEEEGINOOPRRSTY 10
138 10 CDEEEGHILLLNOOST 4
212 15 AABBCEEEEHIILMNNOPRRRSSTUUVY 3

如果您没有足够的内存,您可以尝试迭代数据框的行:

lst = []
for idx, row in df.iterrows():
if SequenceMatcher(None, row['Name_x'], row['Name_y']).ratio() > 0.7:
lst.append(row[['PartnerId_x', 'Name_x', 'PartnerId_y']])

pd.concat(lst, axis=1).T

关于python - Pandas 中的序列相似度匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59783162/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com