Python Numpy检测列表中的递增范围
我有一个列表,看起来像这样(实际上它更大)Python Numpy检测列表中的递增范围,python,numpy,math,Python,Numpy,Math,我有一个列表,看起来像这样(实际上它更大) 1,2,3,4,6,7,9,12,14,15,16 我想自动检测没有间隙的范围,这样我就可以得到这样的元组数组 (1,4)、(6,7)、(9,9)、(12,12)、(14,16) 在numpy有什么有效的方法可以做到这一点?方法#1 我们将使用循环切片的方法,但在预处理部分使用NumPy进行所有计算以获得性能。对数组进行切片只是对视图进行操作,因此应该非常有效。这里有一个实现这些目标的方法- def start_stop_with_seq(a):
1,2,3,4,6,7,9,12,14,15,16
我想自动检测没有间隙的范围,这样我就可以得到这样的元组数组
(1,4)、(6,7)、(9,9)、(12,12)、(14,16)
在numpy有什么有效的方法可以做到这一点?方法#1
我们将使用循环切片的方法,但在预处理部分使用NumPy进行所有计算以获得性能。对数组进行切片只是对视图进行操作,因此应该非常有效。这里有一个实现这些目标的方法-
def start_stop_with_seq(a):
m = np.r_[True,np.diff(a)!=1,True]
idx = np.flatnonzero(m)
return [(a[i],a[j-1]) for (i,j) in zip(idx[:-1],idx[1:])]
样本运行-
In [115]: a
Out[115]: [1, 2, 3, 4, 6, 7, 9, 12, 14, 15, 16]
In [116]: start_stop_with_seq(a)
Out[116]: [(1, 4), (6, 7), (9, 9), (12, 12), (14, 16)]
方法#2
我们可以将向量化解决方案的输入列表索引到一个数组中,并使用索引替换上一个切片部分-
def start_stop_with_seq_v2(a):
a = np.asarray(a)
m = np.r_[True,np.diff(a)!=1,True]
return np.c_[a[m[:-1]], a[m[1:]]]
给定样本的输出-
In [163]: start_stop_with_seq_v2(a)
Out[163]:
array([[ 1, 4],
[ 6, 7],
[ 9, 9],
[12, 12],
[14, 16]])
如果输出有许多间隔,这种方法是有意义的
标杆管理
在一个更大(类似于给定样本)的数据集上进行测试-
In [217]: np.random.seed(0)
In [218]: a = np.unique(np.random.randint(0,100000,(200000))).tolist()
In [219]: %timeit intspan(a).ranges()
29.9 ms ± 343 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [220]: %timeit start_stop_with_seq(a)
14.3 ms ± 84.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [221]: %timeit start_stop_with_seq_v2(a)
6.78 ms ± 57.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
不是在numpy中,但是这里有一种方法,使用它比intspan有什么优势吗?@user2741831不确定。没有与intspan合作过。基准测试并让我知道?我看看是否能做到。但如果它足够好的话,我可能会坚持下去it@user2741831根据大众需求,增加了基准测试。满足您的需要?@user2741831如果您的问题已得到回答或有帮助,您可以接受并投票。更多信息-