首页 > 解决方案 > 在 numpy 矩阵中查找最长和最短的 1 或 0 序列的开始/停止位置和长度

问题描述

我有一个 numpy 矩阵,看起来像:

matrix = [[0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
           0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 1., 1., 0., 0., 0.,
           0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
         [0., 0., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
           1., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
           0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
         [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
           0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
           0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]]  

我如何获得最长的 1 或 0 序列的长度?另外我将如何获得他们的开始和停止位置?

有没有更简单的 numpy 方式来完成这项工作?

输出格式是灵活的,只要它表示内部列表索引、长度值和值的列表索引。

示例:
LONGEST ONES:(1, 16, 2, 17内部列表的索引,长度,最长 1s 序列索引开始,最长 1s 序列结束位置)。或 [1, 16, 2, 17]/(1, 16, 2, 17)
最长零:2, 45, 0, 45

不是这些问题的重复,因为这涉及矩阵:
找到最长的 1 序列的起始位置

应在所有列表中考虑结果(最长)。
当到达内部列表的末尾时,序列计数不会继续。

标签: pythonnumpy

解决方案


使用Divakar's base answer,您可以通过使用np.vectorize、设置参数signature和进行简单的数学运算来获得所需的内容。

举个例子,

m = np.array(matrix)

def get_longest_ones_matrix(b):
    idx_pairs = np.where(np.diff(np.hstack(([False], b==1, [False]))))[0].reshape(-1,2)
    if not idx_pairs.size: return(np.array([0,0,0]))

    d = np.diff(idx_pairs, axis=1).argmax()

    start_longest_seq = idx_pairs[d,0]
    end_longest_seq   = idx_pairs[d,1]

    l = end_longest_seq - start_longest_seq
    p = start_longest_seq % 45
    e = end_longest_seq - 1
    return(np.array([l,p,e])) 

s = m.shape[-1]

v = np.vectorize(get_longest_ones_matrix, signature=f'(s)->(1)')
x = v(m)

哪个产量

[[ 3 26 28]
 [16  2 17]
 [ 0  0  0]]

然后,

a = x[:,0].argmax()
print(a,x[a])
1 [16  2 17]

推荐阅读