python – 如何加速400万集交叉点?
作者:互联网
我是一名缺乏经验的程序员,正在通过Python进行大量的生物信息学练习.
一个问题区域计算名称组之间的集合交集中的元素,以及计算在字典中的存储.每个列表有两个2000个名称组;名称组中的名称是物种的拉丁名称.例如:
list__of_name_groups_1 = [
['Canis Lupus', 'Canis Latrans'],
['Euarctos Americanus', 'Lynx Rufus'],
...
]
list__of_name_groups_2 = [
['Nasua Narica', 'Odocoileus Hemionus'],
['Felis Concolor', 'Peromyscus Eremicus'],
['Canis Latrans', 'Cervus Canadensis']
...
]
我需要一个字典,其中包含名称组之间的所有交叉点大小,例如
>>> intersections
{ (0, 0): 0, (0, 1): 0, (0, 2): 1, (1, 0): 0, (1, 1): 0, (2, 1): 0,
(2, 0): 1, (2, 1): 0, (2, 2): 0 }
(‘Canis Latrans’出现在第一个列表的元素0中,第二个列表中的元素2出现.)
我有一个有效的算法实现,但运行速度太慢.
overlap = {}
for i in list_of_lists_of_names_1:
for j in list_of_lists_of_names_2:
overlap[(i,j)] = len(set(i) & set(j))
有没有更快的方法来计算集合交叉点中的元素数量?
(你好主持人……尼克,这个修改过的帖子实际上问的问题与我正在处理的问题略有不同.虽然你的答案对于解决这个问题非常好,但我担心你建议的方法是实际上对我正在尝试做的事情没有用.我非常感谢你在答案中付出的时间和精力,以及编辑这篇文章,但我会要求将这篇文章还原为原文.)
解决方法:
首先,Python集很擅长查找交集(它们使用散列),但是您的代码反复构造相同的集合.例如.如果这两个列表各包含2000个元素[你的意思是外部或内部列表那么长吗?],只有4000个不同的集合要计算,但你的代码计算2000 x 2000 x 2 = 800万集.
所以计算一次4000套:
list_of_name_tuples_1 = [("a", "aa"), ("b", "bbb"), ("c", "cc", "ccc")]
list_of_name_tuples_2 = [("a", "AA"), ("b", "BBB"), ("c", "cc", "CCC")]
name_sets_1 = [set(i) for i in list_of_name_tuples_1]
name_sets_2 = [set(i) for i in list_of_name_tuples_2]
overlap = {}
for l1, s1 in zip(list_of_name_tuples_1, name_sets_1):
for l2, s2 in zip(list_of_name_tuples_2, name_sets_2):
overlap[(l1, l2)] = len(s1 & s2)
Python列表是不可删除的,因此它们不能用于dict键,因此我将名单列表更改为名称列表.
(此代码假设您正在使用Python 3,其中zip()返回迭代器.如果您使用的是Python 2,则调用itertools.izip()以获取配对元素上的迭代器.)
其次,考虑将重组重叠视为一个词典,而不是一个由元组索引的词典.
list_of_name_tuples_1 = [("a", "aa"), ("b", "bbb"), ("c", "cc", "ccc")]
list_of_name_tuples_2 = [("a", "AA"), ("b", "BBB"), ("c", "cc", "CCC")]
name_sets_1 = [set(i) for i in list_of_name_tuples_1]
name_sets_2 = [set(i) for i in list_of_name_tuples_2]
overlap = {}
for l1, s1 in zip(list_of_name_tuples_1, name_sets_1):
d = overlap.setdefault(l1, {})
for l2, s2 in zip(list_of_name_tuples_2, name_sets_2):
d[l2] = len(s1 & s2)
这可以在后续代码中节省大量工作,后者代码将通过重叠[l1] [l2]而不是重叠[(l1,l2)](没有元组构造或哈希生成)来访问它,并且嵌套循环可以获取d =在外循环中重叠[l1]然后在内循环中访问d [l2].
标签:python,set,bioinformatics 来源: https://codeday.me/bug/20190706/1394579.html