Python 嵌套列表长度不等的多元素相似度计算
我有一个嵌套列表,每一个元素都有不同的长度:Python 嵌套列表长度不等的多元素相似度计算,python,list,similarity,Python,List,Similarity,我有一个嵌套列表,每一个元素都有不同的长度: lst = [[a,bcbcbcbcbc],[e,bbccbbccb],[i,ccbbccbb],[o,cbbccbb]] 我的输出是具有以下外观的数据帧的csv: comparison similarity_score a:e *some score a:i *some score a:o *some score e:i *some
lst = [[a,bcbcbcbcbc],[e,bbccbbccb],[i,ccbbccbb],[o,cbbccbb]]
我的输出是具有以下外观的数据帧的csv:
comparison similarity_score
a:e *some score
a:i *some score
a:o *some score
e:i *some score
e:o *some score
i:o *some score
我的代码:
similarity = []
for i in lst:
name = i[0]
string = i[1]
score = 0.0
length =(len(string))
for i in range(length):
if string[i]==string[i+1]:
score += 1.0
new_score = (100.0*score)/length
name_seq = name[i] + ':' + name[i+1]
similarity.append(name_seq,new_score)
similarity.pdDataFrame(similarity, columns = ['comparison' , 'similarity_score'])
similarity.to_csv('similarity_score.csv')
但我收到了一个错误:
if codes[i]==codes[i+1]:
IndexError: string index out of range
有什么建议吗?谢谢 根据Python的文档
range
通过示例执行以下操作:
>>>范围(10)[0,1,2,3,4,5,6,7,8,9] 在代码中(假设变量名未更改): 换句话说,给定一个输入
bcb
,if语句将查看以下索引:
(0,1)(1,2)
(2,3)
根据Python的文档range
通过示例执行以下操作:
>>>范围(10)
[0,1,2,3,4,5,6,7,8,9]
在代码中(假设变量名未更改):
换句话说,给定一个输入bcb
,if语句将查看以下索引:
(0,1)
(1,2)
(2,3)我认为您最大的问题是,在顶层,您只是一次迭代一对名称、字符串,而不是您希望在输出中看到的一对名称、字符串(如成对名称a:e
所示)
稍后您将尝试为名称
和字符串
值编制索引,但这样做并不能达到您的目的(将两个字符串相互比较以计算分数),因为您只访问同一字符串中的相邻字符。您得到的异常是因为i+1
可能会超出字符串的末尾。由于将i
用于内部循环中的索引和从外部循环中获取的项目(名称、字符串对),因此会出现进一步的混淆
要获得成对的对,我建议使用itertools.compositions
:
import itertools
for [name1, string1], [name2, string2] in itertools.combinations(lst, 2):
现在,您可以在循环的其余部分使用两个名称和两个字符串变量
我不能完全确定我是否理解如何比较字符串以获得分数,因为它们彼此的长度不同。如果只想比较字符串的初始部分(并忽略较长字符串的尾随位),可以使用zip
获取两个字符串之间的对应字符对。然后可以在生成器表达式中比较它们,并将bool
结果相加(True
是整数1
的特殊版本,False
是0
的版本)。然后可以除以字符串长度中较小的一个(或者如果要惩罚长度差异,可以除以较大的一个):
还有一个更明显的问题,就是您使用两个参数调用append
。如果您真的想追加一个2元组,则需要一组额外的括号:
similarity.append((name_seq, new_score))
我认为您最大的问题是,在顶层,您只需一次迭代一对名称、字符串
对,而不是您希望在输出中看到的一对名称、字符串
对(如成对名称a:e
所示)
稍后您将尝试为名称
和字符串
值编制索引,但这样做并不能达到您的目的(将两个字符串相互比较以计算分数),因为您只访问同一字符串中的相邻字符。您得到的异常是因为i+1
可能会超出字符串的末尾。由于将i
用于内部循环中的索引和从外部循环中获取的项目(名称、字符串对),因此会出现进一步的混淆
要获得成对的对,我建议使用itertools.compositions
:
import itertools
for [name1, string1], [name2, string2] in itertools.combinations(lst, 2):
现在,您可以在循环的其余部分使用两个名称和两个字符串变量
我不能完全确定我是否理解如何比较字符串以获得分数,因为它们彼此的长度不同。如果只想比较字符串的初始部分(并忽略较长字符串的尾随位),可以使用zip
获取两个字符串之间的对应字符对。然后可以在生成器表达式中比较它们,并将bool
结果相加(True
是整数1
的特殊版本,False
是0
的版本)。然后可以除以字符串长度中较小的一个(或者如果要惩罚长度差异,可以除以较大的一个):
还有一个更明显的问题,就是您使用两个参数调用append
。如果您真的想追加一个2元组,则需要一组额外的括号:
similarity.append((name_seq, new_score))
numPlaces在哪里初始化?代码[i]==代码[i+1]不会出现在代码段中,除非您指的是字符串[i]==字符串[i+1]什么是numPlaces
(可能应该是length
)?为什么异常中的行与显示的代码中的任何行都不匹配?不管怎么说,我认为您对I
感到困惑,因为您在不同的时间对两个不同的事物使用相同的变量名。如果name
在您的列表中是a
,那么您所做的name[i+1]
就毫无意义了。@Blckknght感谢您的更正。我必须承认我对for循环中的I很困惑。numPlaces初始化在哪里?代码[i]==代码[i+1]不会出现在代码段中,除非您指的是字符串[i]==字符串[i+1]什么是numPlaces
(可能应该是length
)?为什么异常中的行与显示的代码中的任何行都不匹配?不管怎么说,我认为您对I
感到困惑,因为您在不同的时间对两个不同的事物使用相同的变量名。如果name
在您的列表中是a
,那么您所做的name[i+1]
就没有任何意义了。@Blckkng