我有一个numpy.array
由零和一组成,例如:
import numpy
a = numpy.array([0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1])
现在我需要获取每个序列中 1 的第一个和最后一个索引。如果我使用 where
,我可以获得数组中每个 1 的索引:
ones = numpy.where(a == 1)
# ones = (array([ 3, 4, 5, 6, 9, 10, 14, 15, 16, 17], dtype=int64),)
但我只想得到边界,这意味着:
# desired:
ones = (array([ 3, 6, 9, 10, 14, 17], dtype=int64),)
你能帮我一下,如何达到这个结果吗?谢谢
最佳答案
您可以使用按位运算符和np.where
进行移位和比较来找到这些序列的开头和结尾获取相应的索引:
def first_and_last_seq(x, n):
a = np.r_[n-1,x,n-1]
a = a==n
start = np.r_[False,~a[:-1] & a[1:]]
end = np.r_[a[:-1] & ~a[1:], False]
return np.where(start|end)[0]-1
检查建议的示例:
a = np.array([0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1])
first_and_last_seq(a, 1)
# array([ 3, 6, 9, 10, 14, 17])
或者使用以下数组:
a = np.array([5,5,5,6,2,3,5,5,5,2,3,5,5])
first_and_last_seq(a, 5)
# array([ 3, 6, 9, 10, 14, 17])
更多详细信息:
检查 numpy 中连续值的简单方法是使用 bitwise operators比较数组的移位版本。请注意,~a[:-1] & a[1:]
正在执行此操作。第一项是数组切片直到最后一个元素,第二项是从第一个元素开始的切片。
请注意,a
是一个 bool 数组,给定 a = a==n
。在上面的情况下,我们采用第一个移位 bool 数组的 NOT
(因为我们想要一个 True
,所以值为 False
。并且通过与下一个值进行按位 AND
运算,我们只有 True
下一个样本是 True
这样我们就设置为 True
仅序列开始的索引(即我们已匹配子序列[False, True]
)
现在相同的逻辑适用于end
。通过对两个数组和 np.where
进行“或”运算,我们可以获得所有开始和结束索引。
关于python - Numpy 一维数组 - 查找相同数字的子序列的边界索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61760669/