嵌套lis长度不等的多元素相似性计算

2024-04-25 16:52:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个嵌套列表,每一个元素都有不同的长度:

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

有什么建议吗?谢谢!你知道吗


Tags: csvnameinnewforstringifrange
2条回答

我认为您最大的问题是,在顶层,您只是一次迭代一对name,string,而不是您希望在输出中看到的一对name,string(如成对的名称a:e所示)。你知道吗

稍后您将尝试索引namestring值,但这样做并没有达到您想要的效果(将两个字符串相互比较以计算分数),因为您只访问同一字符串中的相邻字符。你得到的例外是因为i+1可能会离开字符串的末尾。由于使用i表示内部循环中的索引和从外部循环中获取的项(即name, string对),因此会有进一步的混淆。你知道吗

要获得成对的,我建议使用itertools.combinations

import itertools

for [name1, string1], [name2, string2] in itertools.combinations(lst, 2):

现在可以在循环的其余部分使用两个名称和两个字符串变量。你知道吗

我不完全确定我是否理解你想要如何比较这些字符串来得到你的分数,因为它们彼此的长度不同。如果只想比较字符串的初始部分(忽略较长字符串的尾随位),可以使用zip来获取两个字符串之间的对应字符对。然后可以在生成器表达式中比较它们并将bool结果相加(True是整数1的特殊版本,False0的版本)。然后可以除以字符串长度中的较小值(如果要惩罚长度差异,则可以除以较大值):

common_letters = sum(c1 == c2 for c1, c2 in zip(string1, string2))
new_score = common_letters * 100 / min(len(string1), len(string2))

还有一个更明显的问题,就是用两个参数调用append。如果您真的想附加一个2元组,则需要一组额外的括号:

similarity.append((name_seq, new_score))

根据Python的文档range通过示例执行以下操作:

>>>range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

在代码中(假设变量名没有更改):

...
length =(len(string))            # For an input of 'bcb' length will be 3
for i in range(length):          # For an input of 'bcb' range will be [0, 1, 2]
    if string[i]==string[i+1]:   # When i == 2 i + 1 == 3 which gives you the
                                 # IndexError: string index out of range
...

换句话说,给定一个输入bcb,if语句将查看以下索引:

(0,1)
(1,2)
(2,3)< 本例中的3是您的问题。你知道吗

要解决问题,请从[0, len(string) - 1]迭代

相关问题 更多 >