【发布时间】:2014-06-06 18:23:38
【问题描述】:
我有很多间隔(大约 5k 到 10k)。这些元素有一个开始和结束位置;像 (203, 405)。间隔的坐标存储在列表中。
我想确定每对间隔之间重叠部分的坐标和长度。这可以按如下方式完成:
# a small list for clarity, with length normally around 5000s
cList = ((20, 54), (25, 48), (67, 133), (90,152), (140,211), (190,230))
for i, c1 in enumerate(cList[:-1]): # a linear pairwise combination
for c2 in cList[i + 1:]:
left = max(c1[0], c2[0])
right = min(c1[1], c2[1])
overlap = right - left
if overlap > 0:
print "left: %s, right: %s, length: %s" % (left, right, overlap)
导致:
left: 25, right: 48, length: 23
left: 90, right: 133, length: 43
left: 140, right: 152, length: 12
left: 190, right: 211, length: 21
可以看出,它可以工作......因为这可能需要相当长的时间(20 秒)我的问题是,我将如何优化它?当第二个循环的开始位置超过第一个结束位置时,我试图切断第二个for循环:
if c1[1] < c2[0]:
break
这大大减少了程序时间,但产生的重叠次数比以前少了大约三倍,因此结果肯定是无效的。这是由长度远大于前面元素的元素造成的。
我确信有一些数学技巧可以解决这个问题
【问题讨论】:
-
如果列表是
[(0, 4), (1, 5), (2, 6)],那么您有一个复杂的多重重叠模式怎么办?你还想要成对重叠的结果吗? (在这种情况下,重叠间隔本身也会重叠。) -
如果列表是
[(0, 4), (2, 6), (4, 8), (6, 10)]怎么办?您想要[(2, 4), (4, 6), (6, 8)]、[(2, 8)]或其他的输出吗? -
这个(基因组)数据肯定包含多重重叠。但在我的情况下,检索成对重叠才是有趣的。我理解你对重叠重叠的意思。在上面的例子中,它可能有点令人困惑。真实数据由对象组成,而不仅仅是坐标...
-
我想要单独的成对重叠,所以 [(2,8)] 不正确。
-
@Benjamin 请编辑您的问题以提及您想要成对重叠。正如它所读的那样,您似乎想要所有区域重叠的片段