【问题标题】:Numpy find indices of groups with same valueNumpy查找具有相同值的组的索引
【发布时间】:2018-10-13 13:17:15
【问题描述】:

我有一个由 0 和 1 组成的 numpy 数组:

y=[1,1,1,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,1,1]

我想计算一组(或零)的索引。所以对于上面的例子,一组的结果应该类似于:

result=[(0,2), (8,9), (16,19)]

(如何)我可以用 numpy 做到这一点吗?我没有发现任何类似 group-by 函数的东西。

我尝试了np.ediff1d,但找不到一个好的解决方案。并不是说数组可能会或可能不会以一组开头/结尾:

import numpy as np

y = [1,1,1,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,1,1]
mask = np.ediff1d(y)
starts = np.where(mask > 0)
ends = np.where(mask < 0)

我还在这里找到了部分解决方案: Find index where elements change value numpy

但是那个只给了我值变化的索引。

【问题讨论】:

    标签: python arrays numpy


    【解决方案1】:

    我们可以做这样的事情,适用于任何通用数组 -

    def islandinfo(y, trigger_val, stopind_inclusive=True):
        # Setup "sentients" on either sides to make sure we have setup
        # "ramps" to catch the start and stop for the edge islands
        # (left-most and right-most islands) respectively
        y_ext = np.r_[False,y==trigger_val, False]
    
        # Get indices of shifts, which represent the start and stop indices
        idx = np.flatnonzero(y_ext[:-1] != y_ext[1:])
    
        # Lengths of islands if needed
        lens = idx[1::2] - idx[:-1:2]
    
        # Using a stepsize of 2 would get us start and stop indices for each island
        return list(zip(idx[:-1:2], idx[1::2]-int(stopind_inclusive))), lens
    

    示例运行 -

    In [320]: y
    Out[320]: array([1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1])
    
    In [321]: islandinfo(y, trigger_val=1)[0]
    Out[321]: [(0, 2), (8, 9), (16, 19)]
    
    In [322]: islandinfo(y, trigger_val=0)[0]
    Out[322]: [(3, 7), (10, 15)]
    

    或者,我们可以使用diff 来获得切片比较,然后简单地使用2 列进行整形以替换步长切片,从而给自己一个单线 -

    In [300]: np.flatnonzero(np.diff(np.r_[0,y,0])!=0).reshape(-1,2) - [0,1]
    Out[300]: 
    array([[ 0,  2],
           [ 8,  9],
           [16, 19]])
    

    【讨论】:

    • 您能详细解释一下更快的方法是如何工作的吗?
    • 我使用了第二种解决方案,它有效。我将这篇文章标记为答案,尽管几周后我可能会很难再次理解这一点:)
    • 对于 Python 3,islandof 的最后一行,zip(...) 应替换为 list(zip(...))。这是因为zip 在 Python 3 中返回一个迭代器。
    猜你喜欢
    • 1970-01-01
    • 2020-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多