在 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】:

您可以将输入读入dicts 的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 文件中的所有行组合中应用字符串匹配逻辑 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

获取 Pandas DataFrame 列中字符串列表中的所有行 - 此模式具有匹配组

删除CSV文件中不以python中的数字开头的所有行

csv 文件中的模式匹配并附加到匹配的行

使用python批量将匹配行附加到csv文件

将 CSV 文件与批处理文件合并,包括每行中的文件名

如何从 sql 创建 csv 文件获取逻辑应用程序上的行