我可以找到相似的条目并将它们分组吗?
我有一个文件,里面记录了用户输入的信息,格式是这样的:
- 用户搜索的书名,搜索次数
举几个例子:
- A Wrinkle in Time, 100
- The Adventures of Huckleberry Finn, 100
- Wrinkle in Time, 20
- Peter Pan, 100
- rinkle in time, 5
- Huckleberry Finn, 100
- Adventures of Huckleberry Finn, 150
- Time wrinkle, 2
书名有很多不同的写法,比如拼写错误、用词不当、顺序不对,或者名字稍微不同。因为这些原因,当我们按字母顺序(A到Z)对列表进行排序时,书名不会被归为一类:
- A Wrinkle in Time, 100
- Wrinkle in Time, 20
- rinkle in time, 5
- Time wrinkle, 2
- Peter Pan, 100
- The Adventures of Huckleberry Finn, 100
- Huckleberry Finn, 100
- Adventures of Huckleberry Finn, 150
A Wrinkle in Time
这些书名被归为一组,而 Huckleberry Finn
的书名又是另一组,每一行仍然保留了它原来的搜索次数。
有没有办法通过模糊逻辑(比如使用 Levenshtein 距离来进行分组)在 Python 或 Ruby 中重新排序这些书名?如果可以的话,有什么简单直接的方法呢?这个问题 在 Python 中分组相似条目 和我的情况类似,只不过我用的是字母字符串而不是数字。
2 个回答
2
如果你能得到一个已知有效的标题列表,那会让你的工作轻松很多:
import csv
from fuzzywuzzy import process
from itertools import groupby
good_titles = [
"a wrinkle in time",
"the adventures of huckleberry finn",
"peter pan"
]
def best_title(title):
return process.extractOne(title.lower(), choices=good_titles)[0]
def read_csv(fname, header=False, **kwargs):
with open(fname, "rb") as inf:
incsv = csv.reader(inf, **kwargs)
if header:
head = next(incsv, None)
for row in incsv:
yield row
def main():
searches = read_csv("search_data.csv", header=True)
searches = [(best_title(title), int(num), title) for title,num in searches]
searches.sort(key=lambda x: (x[0], -x[1], x[2]))
for key,items in groupby(searches, lambda s:s[0]):
for bt, num, t in items:
print("{:40} {:>5}".format(t, num))
print('')
if __name__=="__main__":
main()
会产生
A Wrinkle in Time 100
Wrinkle in Time 20
rinkle in time 5
Time wrinkle 2
Peter Pan 100
Adventures of Huckleberry Finn 150
Huckleberry Finn 100
The Adventures of Huckleberry Finn 100
2
当然可以,我们使用的是 FuzzyWuzzy。网上有一些不错的教程。简单来说,如果我要做这个,我会用一个递归函数来找匹配的东西。
我刚开始用的时候遇到了一些问题,所以我问了 这个问题。
如果你有一组已知的项目来进行匹配,那就简单多了,但我问的问题是关于你一开始不想限制输入集合的情况。
不过要开始的话,可以看看 这个例子。