我正在寻找一种高效且快速的方法来在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
任何帮助将不胜感激!
答案 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_a
和idx_b
中给出。