Database 使用歌曲标题列表比较两个文件的最简单方法
我有两个歌曲标题列表,每个都在一个纯文本文件中,这是许可歌词文件的文件名-我想检查短列表标题(针)是否在长列表(草堆)中。脚本/应用程序应该返回不在大海捞针中的标题列表 我更喜欢使用Python或shell脚本(BASH),或者只使用能够处理所需模糊性的VisualDiff程序 主要的问题是,标题需要模糊匹配,以考虑数据输入错误以及可能的单词顺序 Haystack示例(注意一些重复和接近重复的线,突出显示匹配项): 针样:Database 使用歌曲标题列表比较两个文件的最简单方法,database,list,comparison,recordset,fuzzy-comparison,Database,List,Comparison,Recordset,Fuzzy Comparison,我有两个歌曲标题列表,每个都在一个纯文本文件中,这是许可歌词文件的文件名-我想检查短列表标题(针)是否在长列表(草堆)中。脚本/应用程序应该返回不在大海捞针中的标题列表 我更喜欢使用Python或shell脚本(BASH),或者只使用能够处理所需模糊性的VisualDiff程序 主要的问题是,标题需要模糊匹配,以考虑数据输入错误以及可能的单词顺序 Haystack示例(注意一些重复和接近重复的线,突出显示匹配项): 针样: You Are Good (I Want To Scream It Ou
You Are Good (I Want To Scream It Out)
You Are My Strength (In The Fullness)
You Are My Vision O King Of My Heart
You Are The King Of Glory (Hosanna To The Son)
**You Chose The Cross (Lost In Wonder)**
**Your Grace Is Enough (This Is Our God)**
**Your Love Is Amazing Steady And Unchanging**
**Your Love Shining Like The Sun**
请注意,针的标题“你的爱像太阳一样闪耀”只可能与“你的爱”匹配。最好是不匹配,因此任何不确定的标题匹配都应该出现在输出中
comm -1 -3 <(sort haystack.txt) <(sort needle.txt)
comm-1-3您可能想看看fuzzyfuzzy()
提取函数的有用参数是limit、scorer和processor。我在MySQL中做了类似的操作。我使用以下代码来定义Levenshtein距离和比率函数(我从答案中得到):
然后,您可以使用如下查询来比较这两个表
SELECT title, best_match,
levenshtein_ratio(TRIM(LOWER(title)), TRIM(LOWER(best_match))) AS ratio
FROM (
SELECT n.title AS title, (
SELECT h.title
FROM haystack h
ORDER BY levenshtein_ratio(TRIM(LOWER(n.title)), TRIM(LOWER(h.title))) DESC
LIMIT 1
) AS best_match
FROM needle n
) x
ORDER BY ratio DESC
选择一个截止值,低于该值的所有行都没有良好的匹配。如果要直接使用编辑距离,可以使用levenshtein()而不是levenshtein_ratio(),在本例中,使用ORDER BY to ASC
请注意,这并没有针对词序差异的任何特殊规定。此外,如果你的列表很大,比较可能会很慢。模糊模糊可以让你的梦想成真:
import csv
from fuzzywuzzy import fuzz
# Grab CSV data:
with open('needles.csv', 'U') as z:
reader = csv.reader(z)
needles = list(reader)
with open('haystack.csv', 'U') as w:
reader = csv.reader(w)
haystack = list(reader)
# Calculate matches and append to list
NeedlesNotInHaystack = []
Fuzziness = 80 # ADJUST THIS VALUE TO FINE-TUNE RESULTS
for x in needle:
for y in haystack:
if fuzz.ratio(x,y) > Fuzziness:
NeedlesNotInHaystack.append(x)
#Export results to CSV:
with open('Results', 'wb') as csvfile:
temp = csv.writer(csvfile)
temp.writerows(NeedlesNotInHaystack)
与fuzz.ratio不同,您可以使用以下方法获得更好的结果:
fuzz.token_sort_ratio OR fuzz.token_set_ratio
IMO是Python中模糊匹配的最佳+最简明概述如果您想采用OpenRefine的方式,最好是设置一个本地对帐服务器-我建议
将haystack加载到对账服务器中,让OpenRefine处理您的针头文件并将其发送到对账服务
对账服务器会在每个提案中返回一个分数,这样您就可以(我只是以这些分数为例,不要认为它们是理所当然的):
- 批量接受超过0.9的所有内容
- 手动查看0.8和0.9之间的所有内容
- 丢弃0.8以下的所有内容
可能听起来很愚蠢。。。但是我们可以将这两个文件加载到表中,并通过简单的连接来完成。有一些库消除了对90%代码的需要,无需重新发明轮子。你真的成功地让csv工作了吗?我已经在一些测试数据上尝试过了,它会将所有内容与CSV文件的第一行进行匹配。。。
needle (title VARCHAR)
haystack (title VARCHAR)
SELECT title, best_match,
levenshtein_ratio(TRIM(LOWER(title)), TRIM(LOWER(best_match))) AS ratio
FROM (
SELECT n.title AS title, (
SELECT h.title
FROM haystack h
ORDER BY levenshtein_ratio(TRIM(LOWER(n.title)), TRIM(LOWER(h.title))) DESC
LIMIT 1
) AS best_match
FROM needle n
) x
ORDER BY ratio DESC
import csv
from fuzzywuzzy import fuzz
# Grab CSV data:
with open('needles.csv', 'U') as z:
reader = csv.reader(z)
needles = list(reader)
with open('haystack.csv', 'U') as w:
reader = csv.reader(w)
haystack = list(reader)
# Calculate matches and append to list
NeedlesNotInHaystack = []
Fuzziness = 80 # ADJUST THIS VALUE TO FINE-TUNE RESULTS
for x in needle:
for y in haystack:
if fuzz.ratio(x,y) > Fuzziness:
NeedlesNotInHaystack.append(x)
#Export results to CSV:
with open('Results', 'wb') as csvfile:
temp = csv.writer(csvfile)
temp.writerows(NeedlesNotInHaystack)
fuzz.token_sort_ratio OR fuzz.token_set_ratio