代码之家  ›  专栏  ›  技术社区  ›  alpelito7

如何只获取numpy数组中每个递增值的第一次出现?

  •  2
  • alpelito7  · 技术社区  · 5 月前

    在研究首次通过概率时,我遇到了这个问题。我想找到一种NumPythonic方法(没有显式循环),在每一行中只留下第一个严格递增的值 numpy 数组,同时将重复或非递增的值替换为零。例如,如果

    arr = np.array([
        [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5],
        [1, 1, 2, 2, 2, 3, 2, 2, 3, 3, 3, 4, 4],
        [3, 2, 1, 2, 1, 1, 2, 3, 4, 5, 4, 3, 2]])
    

    我想得到输出:

    out = np.array([
        [1, 0, 0, 2, 0, 0, 3, 0, 0, 4, 0, 5, 0],
        [1, 0, 2, 0, 0, 3, 0, 0, 0, 0, 0, 4, 0],
        [3, 0, 0, 0, 0, 0, 0, 0, 4, 5, 0, 0, 0]])
    
    2 回复  |  直到 5 月前
        1
  •  2
  •   wim    5 月前

    每行可以累积的最大值:

    >>> arr
    array([[1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5],
           [1, 1, 2, 2, 2, 3, 2, 2, 3, 3, 3, 4, 4],
           [3, 2, 1, 2, 1, 1, 2, 3, 4, 5, 4, 3, 2]])
    >>> np.maximum.accumulate(arr, axis=1)
    array([[1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5],
           [1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4],
           [3, 3, 3, 3, 3, 3, 3, 3, 4, 5, 5, 5, 5]])
    

    然后,您可以轻松屏蔽非递增值:

    >>> m_arr = np.maximum.accumulate(arr, axis=1)
    >>> np.where(np.diff(m_arr, axis=1, prepend=0), arr, 0)
    array([[1, 0, 0, 2, 0, 0, 3, 0, 0, 4, 0, 5, 0],
           [1, 0, 2, 0, 0, 3, 0, 0, 0, 0, 0, 4, 0],
           [3, 0, 0, 0, 0, 0, 0, 0, 4, 5, 0, 0, 0]])
    
        2
  •  2
  •   ouroboros1    5 月前

    这里有一种方法:

    m = np.hstack(
        (np.ones((arr.shape[0], 1), dtype=bool),
         np.diff(np.fmax.accumulate(arr, axis=1)) >= 1)
         )
    
    out = np.zeros_like(arr)
    
    out[m] = arr[m]
    

    输出:

    array([[1, 0, 0, 2, 0, 0, 3, 0, 0, 4, 0, 5, 0],
           [1, 0, 2, 0, 0, 3, 0, 0, 0, 0, 0, 4, 0],
           [3, 0, 0, 0, 0, 0, 0, 0, 4, 5, 0, 0, 0]])
    

    解释