这个问题是由 SO 上的两个答案引导的两段代码的高潮。我遇到的第一个问题是如何比较两个字符串之间的相似性,我得到了一个很好的答案,如下所示:
代码 1
def get_bigrams(string):
'''
Takes a string and returns a list of bigrams
'''
s = string.lower()
return { s[i:i+2] for i in range(len(s) - 1) }
def string_similarity(str1, str2):
'''
Perform bigram comparison between two strings
and return a percentage match in decimal form
'''
pairs1 = get_bigrams(str1)
pairs2 = get_bigrams(str2)
intersection = set(pairs1) & set(pairs2)
return (2.0 * len(intersection)) / (len(pairs1) + len(pairs2))
之后,我需要一种方法来对名称列表进行排序,以便通过上面的代码运行它们。我在这里得到了代码,如下所示:
代码 2
import itertools
persons = ["Peter parker", "Richard Parker", "Parker Richard", "Aunt May"]
similarity = []
for p1, p2 in itertools.combinations(persons, 2):
similarity.append(string_similarity(p1,p2))
print("%s - %s: " %(p1, p2) + " " + str(string_similarity(p1, p2)))
similarity = sorted(similarity, key=float)
print(similarity)
现在,最后一个障碍是我的数据不在列表中,实际上是从带有主键的数据库中获取的,这是我最终想要跟踪的。这意味着当我比较多个名称时,我需要标记例如 ID 1 和 ID 2 是最多变体的。为了确定这两个 ID 是最大的变体,我需要对上面的“code1”的结果进行排序,如下所示:
Peter parker - Richard Parker: 0.5454545454545454
Peter parker - Parker Richard: 0.5454545454545454
Peter parker - Aunt May: 0.0
Richard Parker - Parker Richard: 0.8333333333333334
Richard Parker - Aunt May: 0.0
Parker Richard - Aunt May: 0.0
[0.0, 0.0, 0.0, 0.5454545454545454, 0.5454545454545454, 0.8333333333333334]
在我的脑海里,而不是那些名字,我需要用于获取名字的主 ID,所以我正在考虑使用字典。有没有办法使用 运行 {PID:Name}、{PID1:Name1}、PID2:Name2} 的字典,使用code2
获取相似度值code1
,对结果进行排序,然后知道相似度最高的名称是 PID1 和 PID3?或者有没有比我现在想的更优雅、更少拉头发的方式……