我有一个字典,例如:
dict = {'group1':["-----AGAAC--C--","-----ATATA-----"],'group2':["------AGGCGGA----","--AAACC----------","--AAACCG---------"]}
,在本词典中,我想通过迭代所有值来相互比较所有值。 想法是比较每个值并在字母位于非字母字符前面时计数。
这是我应该得到的结果(在其前面带有非字母字符的字母数(以下示例中的pipe
为特征)/字符串的长度)
element1与element2
-----AGAAC--C--
-----*****--|--
-----ATATA-----
1/15 = 0.07
元素1与元素2
------AGGCGGA----
--||||*||||||----
--AAACC----------
10/17= 0.59
元素2与元素3
--AAACC----------
--*****|---------
--AAACCG---------
1/17= 0.059
元素1与元素3
------AGGCGGA----
--||||**|||||----
--AAACCG---------
9/17=0.53
这是我用来比较它们并计算第1组得分的代码:
value1="-----AGAAC--C--"
value2="-----ATATA-----"
count=0
for a,b in zip(value1,value2):
print(a.isalpha(),b.isalpha())
if a.isalpha() == True and b.isalpha()==False:
count += 1
if a.isalpha()==False and b.isalpha()== True :
count +=1
print(count/len(value1))
但是我无法自动实现所有价值……有人有想法吗? 谢谢您的帮助。
答案 0 :(得分:2)
这是一种实现方法:
from itertools import combinations
# Input data
dict = {
'group1': ['-----AGAAC--C--', '-----ATATA-----'],
'group2': ['------AGGCGGA----', '--AAACC----------', '--AAACCG---------']
}
# Iterate groups
for group, elements in dict.items():
# Print group name
print(group)
# Iterate every pair of elements
for element1, element2 in combinations(elements, 2):
# Check both elements have the same length
n = len(element1)
if len(element2) != n:
raise ValueError
# Count the number of times character types do not match
count = sum(c1.isalpha() != c2.isalpha() for c1, c2 in zip(element1, element2))
# Compute ratio
ratio = count / n
# Print result
print(f' * {element1} vs {element2}: {ratio:.4f} ({count}/{n})')
print()
输出:
group1
* -----AGAAC--C-- vs -----ATATA-----: 0.0667 (1/15)
group2
* ------AGGCGGA---- vs --AAACC----------: 0.5882 (10/17)
* ------AGGCGGA---- vs --AAACCG---------: 0.5294 (9/17)
* --AAACC---------- vs --AAACCG---------: 0.0588 (1/17)
编辑:如果要收集对得分高于某个阈值的对的列表,可以略微修改上面的代码:
from itertools import combinations
dict = {
'group1': ['-----AGAAC--C--', '-----ATATA-----'],
'group2': ['------AGGCGGA----', '--AAACC----------', '--AAACCG---------']
}
threshold = 0.10
interesting_pairs = []
for group, elements in dict.items():
for element1, element2 in combinations(elements, 2):
n = len(element1)
if len(element2) != n:
raise ValueError
count = sum(c1.isalpha() != c2.isalpha() for c1, c2 in zip(element1, element2))
ratio = count / n
if ratio > threshold:
interesting_pairs.append((element1, element2))
print(interesting_pairs)
# [('------AGGCGGA----', '--AAACC----------'), ('------AGGCGGA----', '--AAACCG---------')]
编辑2:在评论中进行讨论之后,这是又一个变体,将具有一定阈值以上比率的元素可传递地组合在一起。实际上,这本身就是另一个不同的问题,即找到由该关系给出的图的connected components。您可以通过深度优先搜索来做到这一点:
from itertools import combinations
dict = {
'group1': ['-----AGAAC--C--', '-----ATATA-----'],
'group2': ['------AGGCGGA----', '--AAACC----------', '--AAACCG---------']
}
threshold = 0.10
# Find connected elements
connected = {}
for group, elements in dict.items():
for element1, element2 in combinations(elements, 2):
n = len(element1)
if len(element2) != n:
raise ValueError
count = sum(c1.isalpha() != c2.isalpha() for c1, c2 in zip(element1, element2))
ratio = count / n
if ratio > threshold:
connected.setdefault(element1, {element1}).add(element2)
connected.setdefault(element2, {element2}).add(element1)
# Search components with DFS
result = []
visited = set()
for elem, conn in connected.items():
if elem in visited:
continue
visited.add(elem)
conn = set(conn)
pending = list(conn)
while pending:
subelem = pending.pop()
if subelem in visited:
continue
visited.add(subelem)
subconn = connected[subelem]
conn.update(subconn)
pending.extend(subconn)
result.append(conn)
print(result)
# [{'------AGGCGGA----', '--AAACCG---------', '--AAACC----------'}]