【问题标题】:Longest run/island of a number in PythonPython中数字的最长运行/孤岛
【发布时间】:2016-11-03 02:29:08
【问题描述】:

我有一个 0 重复多次的数组,但我想找到最长的一组 0。例如:

myArray= [[1,0],[2,0],[3,0][4,0][5,1][6,0][7,0][8,0][9,0][10,0][11,0][12,0][13,1][14,2][15,0][16,0][17,0][18,0][19,1][20,0]]

所以 Y 坐标的零连续重复了几次,但我需要找到最长的运行。在这种情况下,最长的运行是从 X 坐标 6 到 X 坐标 12 的 7 个重复零。我希望程序告诉我最长的零运行在哪里(在这种情况下,从 X=6 到 X=12)。

谢谢!

【问题讨论】:

    标签: arrays python-2.7 numpy


    【解决方案1】:

    将零视为我们所追求的。因此,我们将尝试将它们分配为布尔数组中的 True 元素。这可以通过myArray[:,1]==0 来实现。接下来,让我们找到0s 的这些区域的上升沿和下降沿。我们可能让0s 触及数组的限制/边界,因此在这些情况下,我们可能会错过看到这样的上升沿和下降沿。因此,为了覆盖这些边界情况,我们可以在两侧填充False's0's,然后分别寻找正负微分值。与这些上升沿和下降沿相对应的索引必须分别是0s 间隔的开始和停止,最后的最大值将是所需的输出。

    我们将有两个版本来实现下面列出的这种想法。

    def max_interval_len_app1(myArray):
        # Construct a grouped differentiated array where 1s indicate start and -1 
        # as stop indices. Then  store such indices.
        grp_diffs = np.diff(np.hstack(([0],(myArray[:,1]==0).astype(int),[0])))
        grp_start_idx = np.where(grp_diffs==1)[0]
        grp_stop_idx = np.where(grp_diffs==-1)[0]
    
        if len(grp_start_idx)==0:
            return 0 # No zeros found
        else:    
            # Get 0's interval lens by subtracting start from each correspondin
            # stop indices. Return the max length 
            return (grp_stop_idx - grp_start_idx).max()
    
    def max_interval_len_app2(myArray):
        # Get indices at which rising and falling edges occur.
        idx = np.where(np.diff(np.hstack(([False],myArray[:,1]==0,[False]))))[0]
    
        if len(idx)==0:
            return 0 # No zeros found
        else:        
            # Since the rising and falling edges happen in pairs we are guaranteed
            # to have an even sized idx . So reshape into Nx2 array and then do 
            # differentiation along the columns, which would be 0s interval lens. 
            # Max of the lengths should be the desired output.
            return np.diff(idx.reshape(-1,2),axis=1).max()
    

    【讨论】:

    • 对不起,我不是很明白,你能详细说明一下吗? np.diff 和 np.hstack 有什么作用?
    • “由于上升沿和下降沿成对发生,我们保证有一个偶数大小的 idx” - 如果序列以零开头但以非零结尾(反之亦然)
    • @ali_m 因此在两侧添加了False/0 的填充,以确保我们有我认为的上升沿和下降沿。很快添加解释。
    • 抱歉,没有发现填充。如果没有非零,这仍然会中断(您将获得整个数组的长度)。
    • @ali_m 是的,应该有错误检查。尽快添加。
    【解决方案2】:

    您可以从对 for 循环中的连续元素编号开始,然后简单地获取最大值的索引。

    >>> cv, a = [], 0
    >>> for x in myArray:
    >>>     if x[1] == 0:
    >>>         a += 1
    >>>     else:
    >>>         a = 0
    >>>     cv.append(a)
    >>> print(a)
    [1, 2, 3, 4, 0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 1, 2, 3, 4, 0, 1]
    
    >>> mi = cv.index(max(cv))  # finds index of *first* maximum
    >>> run = [mi - cv[mi] + 1, mi]
    >>> print(run)
    [5, 11] 
    

    【讨论】:

      猜你喜欢
      • 2020-07-31
      • 2021-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-14
      • 1970-01-01
      相关资源
      最近更新 更多