这将为您提供一个包含所有连续块长度的数组:
np.diff(np.concatenate(([-1],) + np.nonzero(np.diff(a) != 1) + ([len(a)-1],)))
一些测试:
>>> a = [1, 2, 3, 4, 5, 6, 9, 10, 11, 14, 17, 18, 19, 20, 21]
>>> np.diff(np.concatenate(([-1],) + np.nonzero(np.diff(a) != 1) +
([len(a)-1],)))
array([6, 3, 1, 5], dtype=int64)
>>> a = [0, 1, 2, 4, 5, 6]
>>> np.diff(np.concatenate(([-1],) + np.nonzero(np.diff(a) != 1) +
([len(a)-1],)))
array([3, 3], dtype=int64)
要检查是否有至少 4 个项目,只需将上述代码包装在 np.any(... >= 4) 中。
要了解它是如何工作的,让我们从内到外计算出我的第一个示例的结果:
>>> a = [1, 2, 3, 4, 5, 6, 9, 10, 11, 14, 17, 18, 19, 20, 21]
首先,我们计算出连续项目之间的增量:
>>> np.diff(a)
array([1, 1, 1, 1, 1, 3, 1, 1, 3, 3, 1, 1, 1, 1])
然后,我们确定增量不是1 的位置,即一大块连续项开始或结束的位置:
>>> np.diff(a) != 1
array([False, False, False, False, False, True, False, False, True,
True, False, False, False, False], dtype=bool)
我们提取Trues的位置:
>>> np.nonzero(np.diff(a) != 1)
(array([5, 8, 9], dtype=int64),)
上述索引标记连续连续中的最后一项。 Python 切片定义为start 到last+1,因此我们可以将该数组加一,在开头添加一个零,在末尾添加数组的长度,并具有连续序列的所有开始和结束索引,即:
>>> np.concatenate(([0], np.nonzero(np.diff(a) != 1)[0] + 1, [len(a)]))
array([ 0, 6, 9, 10, 15], dtype=int64)
从连续索引中获取差异将为我们提供每个连续块的所需长度。因为我们关心的是差异,而不是在索引中添加一个,所以在我的原始答案中,我选择在前面加上 -1 并附加 len(a)-1:
>>> np.concatenate(([-1],) + np.nonzero(np.diff(a) != 1) + ([len(a)-1],))
array([-1, 5, 8, 9, 14], dtype=int64)
>>> np.diff(np.concatenate(([-1],) + np.nonzero(np.diff(a) != 1) +
([len(a)-1],)))
array([6, 3, 1, 5], dtype=int64)
假设在这个数组中,你确定你想要5 项目块的索引,即这个数组的3 位置的索引。要恢复该块的开始和停止索引,您只需执行以下操作:
>>> np.concatenate(([0], np.nonzero(np.diff(a) != 1)[0] + 1, [len(a)]))[3:3+2]
array([10, 15], dtype=int64)
>>> a[10:15]
[17, 18, 19, 20, 21]