脾气暴躁:找到遮罩边缘的指标

发布于 2021-01-29 14:57:23

我正在尝试找到掩盖段的索引。例如:

mask = [1, 0, 0, 1, 1, 1, 0, 0]
segments = [(0, 0), (3, 5)]

当前的解决方案看起来像这样(并且 非常 慢,因为我的掩码包含数百万个数字):

segments = []
start = 0
for i in range(len(mask) - 1):
    e1 = mask[i]
    e2 = mask[i + 1]
    if e1 == 0 and e2 == 1:
        start = i + 1
    elif e1 == 1 and e2 == 0:
        segments.append((start, i))

有什么办法可以用numpy有效地做到这一点?

我设法对google进行的唯一操作是numpy.ma.notmasked_edges,但它看起来不像我所需要的。

关注者
0
被浏览
79
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    这是一种方法-

    def start_stop(a, trigger_val):
        # "Enclose" mask with sentients to catch shifts later on
        mask = np.r_[False,np.equal(a, trigger_val),False]
    
        # Get the shifting indices
        idx = np.flatnonzero(mask[1:] != mask[:-1])
    
        # Get the start and end indices with slicing along the shifting ones
        return zip(idx[::2], idx[1::2]-1)
    

    样品运行-

    In [216]: mask = [1, 0, 0, 1, 1, 1, 0, 0]
    
    In [217]: start_stop(mask, trigger_val=1)
    Out[217]: [(0, 0), (3, 5)]
    

    用它来获得0s-

    In [218]: start_stop(mask, trigger_val=0)
    Out[218]: [(1, 2), (6, 7)]
    

    在计时100000x扩大命令datasize -

    In [226]: mask = [1, 0, 0, 1, 1, 1, 0, 0]
    
    In [227]: mask = np.repeat(mask,100000)
    
    # Original soln
    In [230]: %%timeit
         ...: segments = []
         ...: start = 0
         ...: for i in range(len(mask) - 1):
         ...:     e1 = mask[i]
         ...:     e2 = mask[i + 1]
         ...:     if e1 == 0 and e2 == 1:
         ...:         start = i + 1
         ...:     elif e1 == 1 and e2 == 0:
         ...:         segments.append((start, i))
    1 loop, best of 3: 401 ms per loop
    
    # @Yakym Pirozhenko's soln
    In [231]: %%timeit
         ...: slices = np.ma.clump_masked(np.ma.masked_where(mask, mask))
         ...: result = [(s.start, s.stop - 1) for s in slices]
    100 loops, best of 3: 4.8 ms per loop
    
    In [232]: %timeit start_stop(mask, trigger_val=1)
    1000 loops, best of 3: 1.41 ms per loop
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看