将字典与自身进行比较,但如果已经比较过,则避免对键进行两次比较
compare a dictionary to itself but avoiding the comparison of a key twice if already compared
拜托,我又需要帮助了。
我有一个名为 vf_to_cluster.txt
的文件,看起来像:
我从中创建了一个名为 vf_accession_to_cluster_groups
的字典,其中键是 vf_accession
(AI0...),值是集群组列表 (['1','2','3'...]
).
我已经通过这种方式编码来做到这一点(我知道这不是一个漂亮的代码,但是我现在可以用我所知道的做的事情抱歉):
f = 'script_folder/vf_to_cluster.txt'
vf_accession_to_cluster_groups = {}
with open(f, 'r') as f6:
for lines in f6.readlines():
lines = lines.replace('[', '')
lines = lines.replace(']', '')
lines = lines.replace(',', '')
lines_split = lines.strip().split(' ')
vf_keys = lines_split[0]
cluster_values = lines_split[1:]
vf_accession_to_cluster_groups[vf_keys] = cluster_values
得到这本词典后,我的主要目标是查看有多少 vf_accessions
(AI0...) 共享相同的集群组。所以我可以说,例如 AI001 和 AI002 共享 4 个簇组,这意味着这两个 vf_accession
可能相同或非常接近(由相同的基因编码)。
我做了这个代码:
for vf_1 in vf_accession_to_cluster_groups.keys():
print '-'*40
for vf_2 in (vf_accession_to_cluster_groups.keys():
res = 0
if vf_1 != vf_2:
for i in vf_accession_to_cluster_groups[vf_1]:
for j in vf_accession_to_cluster_groups[vf_2]:
if i == j :
res = res + 1
print vf_1, vf_2, res
我得到了类似的东西:
我设法放弃了这样的比较:AI001 AI001 或 AI002 AI002...
通过使用 if vf_1 != vf_2
:
但我无法做到不允许这样的比较:
AI014 AI015 之后,我的代码以另一种方式比较它们 AI015 AI014
所以基本上,我想要的是放弃那种类型的比较。如果比较过一次,则不要以另一种方式再次比较它。谁能帮帮我?
此外,如果任何生物信息学家看到我的矩阵,您认为我应该将簇列表的大小包括到我的 vf_accession
比较中,例如:
dist = float(res) / len(set(vf_accession_to_cluster_groups[vf_1] + vf_accession_to_cluster_groups[vf_2]))
感谢大家提供的帮助。
如果您没有数百万个键,您可以将键存储在一个列表中并对它们进行排序(使结果易于阅读)。
cluster_groups = list(vf_accession_to_cluster_groups.keys())
cluster_groups.sort()
现在您可以使用 enumerate
遍历所有键(除了最后一个键,因为您不需要将它与自身进行比较):
for index, vf_1 in enumerate(cluster_groups[:-1]):
并在您刚刚用于外循环的键之后对所有键进行比较循环
for vf_2 in cluster_groups[index + 1:]:
完整代码
cluster_groups = list(vf_accession_to_cluster_groups.keys())
cluster_groups.sort()
for index, vf_1 in enumerate(cluster_groups[:-1]):
print('-'*40)
for vf_2 in cluster_groups[index + 1:]:
res = 0
for i in vf_accession_to_cluster_groups[vf_1]:
for j in vf_accession_to_cluster_groups[vf_2]:
if i == j :
res = res + 1
print(vf_1, vf_2, res)
一些小建议
- 将结果存储在字典中,以便稍后检索。您可以使用字典中的字典。
如果要检查某个项目是否在列表中,只需使用
if item in my_list:
更新代码
cluster_groups = list(vf_accession_to_cluster_groups.keys())
cluster_groups.sort()
results = dict()
for index, vf_1 in enumerate(cluster_groups[:-1]):
print('-'*40)
results[vf_1] = dict()
for vf_2 in cluster_groups[index + 1:]:
res = 0
for i in vf_accession_to_cluster_groups[vf_1]:
if i in vf_accession_to_cluster_groups[vf_2]:
res = res + 1
print(vf_1, vf_2, res)
results[vf_1].update({vf_2: res})
def get_results(key1, key2, results):
if key1 > key2:
key1, key2 = key2, key1
if results.get(key1):
return results[key1].get(key2)
return None
您可以使用 itertools.combinations
每对只获得一次。
在下面的代码中,我定义了一个 Accession
class 来表示文件一行中包含的信息:登录 ID(key
属性)和簇( clusters
属性)。簇以集合的形式存储,这使得计算两个种质之间共有的簇数变得容易。这是在 nb_common
方法中实现的,只需取两个集合之间的交集 (&
) 的长度。由于 __init__
方法中的代码,文件中的每一行都会创建一个 Accession
。加入列表被传递给 combinations
函数,第二个参数是 2
,因为我们需要成对的加入。我们循环生成的对,并使用 nb_common
方法获取当前对的两个加入之间的共同簇数。
这里我还使用了sys.argv[1]
来获取文件作为命令行的第一个参数。
#!/usr/bin/env python
import sys
from itertools import combinations
class Accession(object):
"""This represents an accession and the corresponding clusters."""
def __init__(self, line):
line_parts = line.strip().split(" ")
self.key = line_parts[0]
# "".join(...) re-creates a string representing the list of clusters
# [1:-1] eliminates the brackets
self.clusters = set("".join(line_parts[1:])[1:-1].split(","))
def nb_common(self, other):
return len(self.clusters & other.clusters)
with open(sys.argv[1], "r") as cluster_file:
accessions = [Accession(line) for line in cluster_file]
for (acc1, acc2) in combinations(accessions, 2):
print acc1.key, acc2.key, acc1.nb_common(acc2)
我调用脚本如下:
$ ./compare_accessions.py vf_to_cluster.txt
AI001 AI002 4
AI001 AI004 4
AI001 AI005 4
AI001 AI010 0
AI001 AI011 0
AI001 AI012 4
AI001 AI013 0
AI001 AI014 0
AI001 AI015 5
AI001 AI016 0
AI001 AI017 0
AI002 AI004 4
AI002 AI005 4
AI002 AI010 0
AI002 AI011 0
AI002 AI012 4
AI002 AI013 0
AI002 AI014 0
AI002 AI015 4
AI002 AI016 0
AI002 AI017 0
AI004 AI005 4
AI004 AI010 0
AI004 AI011 0
AI004 AI012 4
AI004 AI013 0
AI004 AI014 0
AI004 AI015 5
AI004 AI016 0
AI004 AI017 0
AI005 AI010 0
AI005 AI011 0
AI005 AI012 4
AI005 AI013 0
AI005 AI014 0
AI005 AI015 4
AI005 AI016 0
AI005 AI017 0
AI010 AI011 0
AI010 AI012 0
AI010 AI013 0
AI010 AI014 1
AI010 AI015 1
AI010 AI016 0
AI010 AI017 0
AI011 AI012 0
AI011 AI013 1
AI011 AI014 0
AI011 AI015 1
AI011 AI016 0
AI011 AI017 0
AI012 AI013 0
AI012 AI014 0
AI012 AI015 4
AI012 AI016 0
AI012 AI017 0
AI013 AI014 0
AI013 AI015 1
AI013 AI016 0
AI013 AI017 0
AI014 AI015 1
AI014 AI016 0
AI014 AI017 0
AI015 AI016 1
AI015 AI017 0
AI016 AI017 0
如何将共同簇的数量转化为距离似乎是一个悬而未决的问题。你可以在 bioinformatics stackexchange site 中提出这个问题,不要忘记介绍你的生物学问题。
拜托,我又需要帮助了。
我有一个名为 vf_to_cluster.txt
的文件,看起来像:
我从中创建了一个名为 vf_accession_to_cluster_groups
的字典,其中键是 vf_accession
(AI0...),值是集群组列表 (['1','2','3'...]
).
我已经通过这种方式编码来做到这一点(我知道这不是一个漂亮的代码,但是我现在可以用我所知道的做的事情抱歉):
f = 'script_folder/vf_to_cluster.txt'
vf_accession_to_cluster_groups = {}
with open(f, 'r') as f6:
for lines in f6.readlines():
lines = lines.replace('[', '')
lines = lines.replace(']', '')
lines = lines.replace(',', '')
lines_split = lines.strip().split(' ')
vf_keys = lines_split[0]
cluster_values = lines_split[1:]
vf_accession_to_cluster_groups[vf_keys] = cluster_values
得到这本词典后,我的主要目标是查看有多少 vf_accessions
(AI0...) 共享相同的集群组。所以我可以说,例如 AI001 和 AI002 共享 4 个簇组,这意味着这两个 vf_accession
可能相同或非常接近(由相同的基因编码)。
我做了这个代码:
for vf_1 in vf_accession_to_cluster_groups.keys():
print '-'*40
for vf_2 in (vf_accession_to_cluster_groups.keys():
res = 0
if vf_1 != vf_2:
for i in vf_accession_to_cluster_groups[vf_1]:
for j in vf_accession_to_cluster_groups[vf_2]:
if i == j :
res = res + 1
print vf_1, vf_2, res
我得到了类似的东西:
我设法放弃了这样的比较:AI001 AI001 或 AI002 AI002...
通过使用 if vf_1 != vf_2
:
但我无法做到不允许这样的比较: AI014 AI015 之后,我的代码以另一种方式比较它们 AI015 AI014 所以基本上,我想要的是放弃那种类型的比较。如果比较过一次,则不要以另一种方式再次比较它。谁能帮帮我?
此外,如果任何生物信息学家看到我的矩阵,您认为我应该将簇列表的大小包括到我的 vf_accession
比较中,例如:
dist = float(res) / len(set(vf_accession_to_cluster_groups[vf_1] + vf_accession_to_cluster_groups[vf_2]))
感谢大家提供的帮助。
如果您没有数百万个键,您可以将键存储在一个列表中并对它们进行排序(使结果易于阅读)。
cluster_groups = list(vf_accession_to_cluster_groups.keys())
cluster_groups.sort()
现在您可以使用 enumerate
遍历所有键(除了最后一个键,因为您不需要将它与自身进行比较):
for index, vf_1 in enumerate(cluster_groups[:-1]):
并在您刚刚用于外循环的键之后对所有键进行比较循环
for vf_2 in cluster_groups[index + 1:]:
完整代码
cluster_groups = list(vf_accession_to_cluster_groups.keys())
cluster_groups.sort()
for index, vf_1 in enumerate(cluster_groups[:-1]):
print('-'*40)
for vf_2 in cluster_groups[index + 1:]:
res = 0
for i in vf_accession_to_cluster_groups[vf_1]:
for j in vf_accession_to_cluster_groups[vf_2]:
if i == j :
res = res + 1
print(vf_1, vf_2, res)
一些小建议
- 将结果存储在字典中,以便稍后检索。您可以使用字典中的字典。
如果要检查某个项目是否在列表中,只需使用
if item in my_list:
更新代码
cluster_groups = list(vf_accession_to_cluster_groups.keys())
cluster_groups.sort()
results = dict()
for index, vf_1 in enumerate(cluster_groups[:-1]):
print('-'*40)
results[vf_1] = dict()
for vf_2 in cluster_groups[index + 1:]:
res = 0
for i in vf_accession_to_cluster_groups[vf_1]:
if i in vf_accession_to_cluster_groups[vf_2]:
res = res + 1
print(vf_1, vf_2, res)
results[vf_1].update({vf_2: res})
def get_results(key1, key2, results):
if key1 > key2:
key1, key2 = key2, key1
if results.get(key1):
return results[key1].get(key2)
return None
您可以使用 itertools.combinations
每对只获得一次。
在下面的代码中,我定义了一个 Accession
class 来表示文件一行中包含的信息:登录 ID(key
属性)和簇( clusters
属性)。簇以集合的形式存储,这使得计算两个种质之间共有的簇数变得容易。这是在 nb_common
方法中实现的,只需取两个集合之间的交集 (&
) 的长度。由于 __init__
方法中的代码,文件中的每一行都会创建一个 Accession
。加入列表被传递给 combinations
函数,第二个参数是 2
,因为我们需要成对的加入。我们循环生成的对,并使用 nb_common
方法获取当前对的两个加入之间的共同簇数。
这里我还使用了sys.argv[1]
来获取文件作为命令行的第一个参数。
#!/usr/bin/env python
import sys
from itertools import combinations
class Accession(object):
"""This represents an accession and the corresponding clusters."""
def __init__(self, line):
line_parts = line.strip().split(" ")
self.key = line_parts[0]
# "".join(...) re-creates a string representing the list of clusters
# [1:-1] eliminates the brackets
self.clusters = set("".join(line_parts[1:])[1:-1].split(","))
def nb_common(self, other):
return len(self.clusters & other.clusters)
with open(sys.argv[1], "r") as cluster_file:
accessions = [Accession(line) for line in cluster_file]
for (acc1, acc2) in combinations(accessions, 2):
print acc1.key, acc2.key, acc1.nb_common(acc2)
我调用脚本如下:
$ ./compare_accessions.py vf_to_cluster.txt
AI001 AI002 4
AI001 AI004 4
AI001 AI005 4
AI001 AI010 0
AI001 AI011 0
AI001 AI012 4
AI001 AI013 0
AI001 AI014 0
AI001 AI015 5
AI001 AI016 0
AI001 AI017 0
AI002 AI004 4
AI002 AI005 4
AI002 AI010 0
AI002 AI011 0
AI002 AI012 4
AI002 AI013 0
AI002 AI014 0
AI002 AI015 4
AI002 AI016 0
AI002 AI017 0
AI004 AI005 4
AI004 AI010 0
AI004 AI011 0
AI004 AI012 4
AI004 AI013 0
AI004 AI014 0
AI004 AI015 5
AI004 AI016 0
AI004 AI017 0
AI005 AI010 0
AI005 AI011 0
AI005 AI012 4
AI005 AI013 0
AI005 AI014 0
AI005 AI015 4
AI005 AI016 0
AI005 AI017 0
AI010 AI011 0
AI010 AI012 0
AI010 AI013 0
AI010 AI014 1
AI010 AI015 1
AI010 AI016 0
AI010 AI017 0
AI011 AI012 0
AI011 AI013 1
AI011 AI014 0
AI011 AI015 1
AI011 AI016 0
AI011 AI017 0
AI012 AI013 0
AI012 AI014 0
AI012 AI015 4
AI012 AI016 0
AI012 AI017 0
AI013 AI014 0
AI013 AI015 1
AI013 AI016 0
AI013 AI017 0
AI014 AI015 1
AI014 AI016 0
AI014 AI017 0
AI015 AI016 1
AI015 AI017 0
AI016 AI017 0
如何将共同簇的数量转化为距离似乎是一个悬而未决的问题。你可以在 bioinformatics stackexchange site 中提出这个问题,不要忘记介绍你的生物学问题。