Python,从范围列表中查找范围是否包含另一个更小的范围

时间:2019-01-23 12:46:08

标签: python range subset

我正在寻找一种高效且快速的方法来在Python 3.x中执行以下操作。只要有性能,我愿意使用Numpy等第三方库。

我有一个包含数十万个条目的范围列表。它们实际上不是range()的,而是边界数字,例如:

list_a = [(1, 100), (300, 550), (551, 1999)]

然后,我迭代了数十万个其他范围(边界数)。我想查找它们是否包含上述现有范围之一。例如:

(0, 600) contains list_a[0] and list_a[1]
(550, 2000) contains list_a[2]
(2000, 2200) does not contain an existing range

现在,执行类似以下操作,对于大量数据来说太慢了:

for start, end in get_next_range():
    for r in list_a:
        if r[0] >= start and r[1] <= end:
            # do something
        else:
            # do something else

任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:1)

我将使用numpy按照以下方式进行操作:

import numpy as np
start = 0
finish = 600
lista = np.array([[1,100],[300,550],[551,1999]])
S = lista[:,0]>start
F = lista[:,1]<finish
contains = np.logical_and(S,F)
ind = list(np.flatnonzero(contains))
print(ind) #print [0, 1]

说明:首先,我将lista设为np.array,然后将其切成两部分:一个是下限([:,0]),第二个是上限([:,1])然后使用比较运算符,得到np.array中的一维bool。使用np.logical_an d,我得到了一个一维np.array,其中True s满足了填充条件,False s供了休息。最后,我使用np.flatnonzero来获取True s的索引。此解决方案假定所有数据均按(lowerboundary,upperboundary)顺序。请检查该解决方案是否足够快达到您的目的。

答案 1 :(得分:0)

假设它们在其中排序,即范围值从不(高,低), 这会将a中的 all 元素与b中的 all 元素同时进行比较:

import numpy as np

list_a = [(1, 100), (300, 550), (551, 1999)]
list_b = [(0, 600), (550, 2000), (2000, 2200), (50, 70)]
a = np.array(a)
b = np.array(b)
comparison = np.logical_and(a[:, 1] >= b[:, 1, None], a[:, 0] <= b[:, 0, None])
idx_a, idx_b = idx = np.nonzero(comparison)
print(a[idx_a])
print(b[idx_b])

array([[   1,  100],
       [ 300,  550],
       [ 551, 1999]])

array([[   0,  600],
       [   0,  600],
       [ 550, 2000]])

这为您提供了b中包含的a中的间隔。索引在idx_aidx_b中给出。