在 csv 文件中的所有行组合中应用字符串匹配逻辑 [关闭]
Posted
技术标签:
【中文标题】在 csv 文件中的所有行组合中应用字符串匹配逻辑 [关闭]【英文标题】:Apply string matching logic across all combinations of rows in csv file [closed] 【发布时间】:2018-09-10 11:08:02 【问题描述】:我正在尝试使用 python 进行字符串匹配。我有 .csv 数据,例如:
Item_ID»Item_Name
101»tomato
102»tomatos
103»tomatoes
104»tomato
(»
s 代表制表符\t
字符。)
我希望输出是这样的:
Item_ID»Item_ID1»Similarity
101»102»92
101»103»73
101»104»100
102»101»92
102»103»85
102»104»92
104»101»100
104»102»92
104»103»73
Item_Name
可以相同但ID不同,相似度应以Item_name
为基础,但要与每个Item_ID
计算。你能帮我写一下python代码吗?
【问题讨论】:
这只是一个例子。很抱歉没有提到这一点。 相似度应基于 Item_name 与 Item_name 的值。例如:“Tomato”(101)可以与字符串“Tomatoes”(102)有 92% 的相似度 好的,但是我们应该如何计算 92% 的值。如果我们无法计算该值,我们就无法创建包含该值的列。请将所需的输出更新为我们可以通过一些可复制的逻辑实际计算的结果。 有点像这样:***.com/questions/36802453/… 所以我下面的解决方案使用difflib.SequenceMatcher
。希望对您有所帮助。
【参考方案1】:
这是我将如何通过pandas
实现您的逻辑。
import pandas as pd
from difflib import SequenceMatcher
from io import StringIO
from itertools import combinations
mystr = StringIO("""Item_ID Item_Name
101 tomato
102 tomatos
103 tomatoes
104 tomato""")
# replace mystr with 'input.csv'
d = pd.read_csv(mystr, delim_whitespace=True).set_index('Item_ID')['Item_Name'].to_dict()
# create dictionary of results
d_out = idx: [i, j, SequenceMatcher(None, d[i], d[j]).ratio()] \
for idx, (i, j) in enumerate(combinations(d, 2))
# create dataframe from dictionary
res = pd.DataFrame.from_dict(d_out, orient='index')
# rename columns
res.columns = ['Item_ID', 'Item_ID1', 'Similarity']
# output to csv
res.to_csv('result.csv', index=False)
结果:
Item_ID Item_ID1 Similarity
0 101 102 0.923077
1 101 103 0.857143
2 101 104 1.000000
3 102 103 0.933333
4 102 104 0.923077
5 103 104 0.857143
【讨论】:
是的,但是如何在“Item_ID”列中添加 104 我也想要相同的行。 将combinations
的两个实例替换为permutations
。那应该可以。【参考方案2】:
您可以将输入读入dict
s 的list
,如我的示例所示。
然后,您可以使用itertools.combinations(data, 2)
获取所有对。
import itertools
import random
def get_similarity(obj1, obj2):
# your own get_similarity function using obj1['name'], obj2['id'], etc
# here I'm just returning random number
return random.randint(1, 100)
data = [
'id': 101, 'name': 'tomato',
'id': 102, 'name': 'tomatos',
'id': 103, 'name': 'tomatoes',
'id': 104, 'name': 'tomato',
]
print('Item_ID1', '\t', 'Item_ID2', '\t', 'Similarity')
for obj1, obj2 in itertools.combinations(data, 2):
similarity = get_similarity(obj1, obj2)
print(obj1['id'], '\t', obj2['id'], '\t', similarity)
这个输出
Item_ID1 Item_ID2 Similarity
101 102 89
101 103 83
101 104 75
102 103 9
102 104 3
103 104 86
在您的示例输出中,您将同一对重复两次(例如,(101, 104) 和 (104, 101)。
如果这是有意的,您可以简单地打印两次相同的对,并交换对象的顺序:
for obj1, obj2 in itertools.combinations(data, 2):
similarity = get_similarity(obj1, obj2)
print(obj1['id'], '\t', obj2['id'], '\t', similarity)
print(obj2['id'], '\t', obj1['id'], '\t', similarity)
【讨论】:
谢谢,也可以在 .CSV 文件上完成吗? 另外,它是创建随机整数还是实际使用任何算法计算字符串相似度? @RishabOberoi 是的!您可以通过创建一个列表,为每行的 CSV 构造一个带有“id”和“name”字段的dict
,并在读取 csv 文件时将dict
推送到列表中。如果你开始学习 Python,我认为这将是一个很好的练习。我只是使用了随机整数,但你应该用你的相似度计算逻辑替换它。
好的,感谢 Eric 的帮助。我会试试你建议的这个解决方案。以上是关于在 csv 文件中的所有行组合中应用字符串匹配逻辑 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章