【问题标题】:NumPy: Finding minimum in submatrices/blocks and corresponding row, column indicesNumPy:在子矩阵/块和相应的行、列索引中找到最小值
【发布时间】:2016-10-26 15:27:26
【问题描述】:

给定一个方阵 M (mxm),由维度 (nxn) 的子矩阵组成,其中 mxm 模 nxn == 0,返回每个子矩阵的所有最小值的矩阵。

例如男:(4x4)

M = array([[19834, 29333, 29333, 33120],
           [ 5148, 25560, 29393,  8083],
           [ 5148, 29393, 25560,  8083],
           [19958, 25748, 25748, 24506]], dtype=uint64)

每个子矩阵 m 为 2x2,返回最小值如下:

M* = array([[ 5148, 8083],
            [ 5148, 8083]], dtype=uint64)

我尝试过重塑数组并调用 min(),但它只允许您在一个轴上这样做。

此外,我还想获得最小值的原始索引,但我假设我必须在生成 M* 后搜索它。

【问题讨论】:

    标签: python numpy matrix


    【解决方案1】:

    您可以将两个轴拆分为另外两个,从而生成一个长度为 24D 数组,每个数组作为这两个拆分轴中的第二个轴,这将是生成的 @987654323 中的第二个和第四个轴@ 大批。然后,只需沿着这两个轴找到 minimum 即可获得所需的输出。

    因此,实现看起来像这样 -

    m,n = M.shape
    out = M.reshape(m//2,2,n//2,2).min(axis=(1,3))
    

    示例运行 -

    In [41]: M
    Out[41]: 
    array([[33, 26, 15, 53, 72, 53],
           [12, 64, 28, 27, 58, 51],
           [61, 42, 70, 92, 61, 95],
           [35, 62, 48, 27, 53, 33]])
    
    In [42]: m,n = M.shape
    
    In [43]: M.reshape(m//2,2,n//2,2).min(axis=(1,3))
    Out[43]: 
    array([[12, 15, 51],
           [35, 27, 33]])
    

    在原始数组对应的每个子矩阵中获取argmins

    为了获得这些 argmins,我们需要做一些额外的工作,如下所列 -

    B = 2 # Blocksize 
    m,n = M.shape
    
    # Reshape into 4D array as discussed for the previous problem
    M4D = M.reshape(m//B,B,n//B,B)
    
    # Bring the second and fourth axes together and then merge.
    # Then, get linear indices within each submatrix
    lidx = M4D.transpose(0,2,1,3).reshape(-1,n//B,B**2).argmin(-1)
    
    # Convert those linear indices into row, col indices corresponding
    # to submatrix and finally corresponding to the original array
    r,c = np.unravel_index(lidx,[B,B])
    row = r + (B*np.arange(m//B)[:,None])
    col = c + B*np.arange(n//B)
    

    样本输入、输出-

    In [170]: M
    Out[170]: 
    array([[40, 91, 90, 72, 86, 44],
           [63, 56, 20, 95, 60, 41],
           [28, 50, 32, 89, 69, 46],
           [41, 41, 33, 81, 30, 63]])
    
    In [171]: np.column_stack((row.ravel(),col.ravel()))
    Out[171]: 
    array([[0, 0],
           [1, 2],
           [1, 5],
           [2, 0],
           [2, 2],
           [3, 4]])
    

    【讨论】:

    • 是否可以获得每个 2x2 子矩阵的最小值的“本地”坐标?因此,M[1, 5] 处的最小值的坐标将是 (1,1)。 ps 感谢您提供的所有惊人的帮助和见解。
    • @user1658296 那就是r,c
    • 我明白了。我想我应该更新问题(?),因为我最终要寻找的是一组形式的元组(内在坐标、本地坐标、最小值)。例如对于最小值 M[1, 5],局部坐标为 (1,1),内在坐标为 (0,2)。所以:((0, 2), (1,1), 41)
    【解决方案2】:

    我认为这可以使用np.hsplitnp.vsplit

    由于python3中的map返回map object,所以在进一步计算之前需要列出map的结果。

    编辑:对于第二个问题,将np.min 更改为np.argmin 将产生一个位置矩阵。

    import numpy as np
    
    M_star = np.array(list(map(lambda x: list(map(lambda x: np.min(x), x)), list(map(lambda x: np.hsplit(x, n), np.vsplit(M, n))))))
    M_star_pos = np.array(list(map(lambda x: list(map(lambda x: np.argmin(x), x)), list(map(lambda x: np.hsplit(x, n), np.vsplit(M, n))))))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-13
      • 1970-01-01
      • 2012-07-30
      • 2023-03-03
      • 1970-01-01
      • 2015-11-03
      • 2021-10-10
      • 2021-09-15
      相关资源
      最近更新 更多