跳过自身迭代列表

如何解决跳过自身迭代列表

我正在尝试在列表中找到相似的电子邮件。为此,

database.head()

    TID PID Names
0   22330   134575  tim
1   22333   134578  tim.rand
2   22328   134571  rand.001
3   22340   134568  pankit090
4   22325   134569  timrook

emailsdb = database['Names'].values.tolist() 现在是迭代部分

list = []
for email in emailsdb :
    result = process.extractBests(email,emailsdb,score_cutoff=85,limit=100)
    list.append(result)

列表输出

[[('tim',100),('tim.rand',90),('timrook',90)],[('tim.rand',('tim',[('rand.001',100)],[('pankit090',('pankit001',89),('pankit002',('pankit003',('pankit004',('pankit005',89)],[('timrook',[('pankit001',('pankit090',[('pankit002',

但是我要避免('tim',100),('tim.rand',100),('rand.001',100),('pankit090',100),('timrook',100 ),('pankit001',100),('pankit002',100),因为它们显然是完美的匹配

解决方法

根据我们在聊天中的讨论,将此问题发布为另一个答案,因为这以完全不同的方式解决了问题。

方法-

  1. 如果使用交换函数获取字符串匹配项,则实际上只能计算距离矩阵的下三角矩阵,因为f(x,y)与f(y,x)相同。

  2. 模糊比不是可交换的,而Levenshtein距离(又称编辑距离,这是模糊匹配的基础)是可交换的。这里不是获得最高分,而是找到它们之间的最小lev距离为

    的字符串。
  3. 因此,您首先获取下三角矩阵的索引,然后对它们进行迭代以计算具有这些索引的电子邮件的lev距离。您不要对距离矩阵f(x,x)的对角线进行迭代,因为它很琐碎,然后将其设置为999之类的较高值,以便可以在每一行中找到最小得分值。

  4. 这将为您提供距离矩阵(请参见输出)。接下来,对于每一行(电子邮件),您都找到最接近的字符串(最小距离)并将其创建为最佳匹配元组(请参见输出)

  5. 现在,这里的问题是,即使字符串NONE匹配得很好,它仍然会贪婪地获取最接近的那个。

  6. 因此,最终您可以在这些字符串之间进行fuzz.ratio运算,并获得模糊分数,然后对其进行过滤。因此,现在,您可以避免垃圾匹配,而仅使真正匹配的垃圾超过特定阈值。这给出了最终匹配字符串(参见输出)

这可能是从算法角度优化代码的最佳选择。

distance matrix = 
[[999.   5.   8.   8.   4.]
 [  5. 999.   8.   9.   4.]
 [  8.   8. 999.   6.   8.]
 [  8.   9.   6. 999.   9.]
 [  4.   4.   8.   9. 999.]]


Best matches = 
[('tim','timrook'),('tim.rand',('rand.001','pankit090'),('pankit090','rand.001'),('timrook','tim')]


final matching strings - 
[('tim','timrook',60),53),'tim',60)]
ArgumentParser
,

这是处理模糊查找然后删除原始电子邮件列表结果的代码。由于这是一个简短列表,因此删除匹配列表与清除原始列表具有相同的效果。请注意,删除过程可能包含在第一个电子邮件循环中,但是为了清楚起见,我将它们分开放置。我添加了zzzz条目以检查得分。

from fuzzywuzzy import fuzz
from fuzzywuzzy import process

# original email list
emailsdb = [
'tim','tim.rand','rand.001','pankit090','pankit001','pankit002','pankit003','pankit004','pankit005','zzzz'
]

print('emailsdb:',emailsdb)

# do fuzzy search and score other emails (including self)
lstres = []
for email in emailsdb :
    result = process.extractBests(email,emailsdb,score_cutoff=85,limit=50)
    lstres.append(result)
    
print('WuzzyResult:',lstres)

# scan match list and create set 
setremove = set()  # no duplicates
for r in lstres:
   setremove |= ({t[0] for t in r})
   
print('setremove:',setremove)

# remove matches from original set
for e in setremove:
   emailsdb.remove(e)
   
print('emailsdb:',emailsdb)

输出:

emailsdb: ['tim','zzzz']

WuzzyResult: [
[('tim',100),90),90)],[('tim.rand',('tim',[('rand.001',100)],[('pankit090',('pankit001',89),('pankit002',('pankit003',('pankit004',('pankit005',89)],[('timrook',[('pankit001',[('pankit002',[('pankit003',[('pankit004',[('pankit005',[('zzzz',100)]
]

setremove: {'pankit002','zzzz','tim.rand'}

emailsdb: []
,

您可以删除不想比较的已知项目(可能是预定义的知识)。可以通过弹出这些项目然后进行比较,然后再将其插入来完成。

这应该可以解决部分问题。在比较之前,我只是pop与列表中的相同元素,然后insert将其返回下一个循环。检查打印的输出以获取更多详细信息-

import pandas as pd
from fuzzywuzzy import fuzz,process

emailsdb = list(df['Names'])

l = []
for i in range(len(emailsdb)) : 
    email = emailsdb[i] #Popping based on index,rather than comparing email in emailsdb
    emailsdb.pop(i) #Pop the same email string in the list of emails
    print("comparing:",[email],'->',emailsdb)
    result = process.extractBests(email,limit=100)
    l.append(result)
    emailsdb.insert(i,email) #Insert it back

print(l)
comparing: ['tim'] -> ['tim.rand','timrook']
comparing: ['tim.rand'] -> ['tim','timrook']
comparing: ['rand.001'] -> ['tim','timrook']
comparing: ['pankit090'] -> ['tim','timrook']
comparing: ['timrook'] -> ['tim','pankit090']

[[('tim.rand',[('tim',[],90)]]

如您所见,冗余比较不是输出的一部分。

注意,我没有将电子邮件列表中的电子邮件与整个电子邮件列表进行比较以将其删除。我只是利用迭代的顺序性质从电子邮件列表中删除第0、1、2,...个索引电子邮件。这是一个很大的加速。

您可以修改此方法,以处理已经知道相似且无需比较的项目集。

P.S:请取悦,请勿使用list作为变量名:)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?