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

使用掩码的逻辑索引在numpy中工作,而不是在Matlab中

  •  0
  • Carpetfizz  · 技术社区  · 6 年前

    我试图用一个稀疏矩阵在MATLAB中重现下面的Python代码。

    >>> print(M)
    [[0 0 0 0 0]
     [0 1 1 1 0]
     [0 1 0 1 0]
     [0 1 1 1 0]
     [0 0 0 0 0]]
    >>> im2var = np.arange(5 * 5).reshape((5, 5))
    >>> A = np.zeros((25, 25), dtype=int)
    >>> A[im2var[M == 1], im2var[M == 1]] = 1
    >>> print(A)
    [[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     [0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     [0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     [0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     [0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0]
     [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     [0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0]
     [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0]
     [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0]
     [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0]
     [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
     [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]]
    

    这是我用MATLAB写的

    M = [
        0 0 0 0 0;
        0 1 1 1 0;
        0 1 0 1 0;
        0 1 1 1 0;
        0 0 0 0 0
    ];
    
    im2var = reshape(1:25, [5 5]);
    A = zeros(25, 25);
    A(im2var(M == 1), im2var(M == 1)) = 1;
    num2str(A)
    

    当我运行MATLAB脚本时,我得到了下面的矩阵,它与Numpy输出明显不同。

    ans =
    
      25x73 char array
    
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  1  1  1  0  0  1  0  1  0  0  1  1  1  0  0  0  0  0  0'
        '0  0  0  0  0  0  1  1  1  0  0  1  0  1  0  0  1  1  1  0  0  0  0  0  0'
        '0  0  0  0  0  0  1  1  1  0  0  1  0  1  0  0  1  1  1  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  1  1  1  0  0  1  0  1  0  0  1  1  1  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  1  1  1  0  0  1  0  1  0  0  1  1  1  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  1  1  1  0  0  1  0  1  0  0  1  1  1  0  0  0  0  0  0'
        '0  0  0  0  0  0  1  1  1  0  0  1  0  1  0  0  1  1  1  0  0  0  0  0  0'
        '0  0  0  0  0  0  1  1  1  0  0  1  0  1  0  0  1  1  1  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
    

    谢谢你的帮助!

    编辑:我也想达到以下效果,但目前的答案似乎不适用于两组索引。

    >>> Mp = np.roll(M, 1, axis=1)
    >>> A[im2var[M==1], im2var[Mp==1]] = -1
    >>> print(A[5:15,5:15])
    [[ 0  0  0  0  0  0  0  0  0  0]
     [ 0  1 -1  0  0  0  0  0  0  0]
     [ 0  0  1 -1  0  0  0  0  0  0]
     [ 0  0  0  1 -1  0  0  0  0  0]
     [ 0  0  0  0  0  0  0  0  0  0]
     [ 0  0  0  0  0  0  0  0  0  0]
     [ 0  0  0  0  0  0  1 -1  0  0]
     [ 0  0  0  0  0  0  0  0  0  0]
     [ 0  0  0  0  0  0  0  0  1 -1]
     [ 0  0  0  0  0  0  0  0  0  0]]
    

    通过使用当前答案的建议,我编写了以下代码。

    M = [
        0 0 0 0 0;
        0 1 1 1 0;
        0 1 0 1 0;
        0 1 1 1 0;
        0 0 0 0 0
    ];
    
    Mp = circshift(M, 1, 2);
    
    ind = find(M);
    indp = find(Mp);
    
    A = zeros(25, 25);
    A(sub2ind(size(A), ind, ind)) = 1;
    A(sub2ind(size(A), ind, indp)) = -1;
    
    num2str(A)
    

    ans =
    
      25x73 char array
    
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  1  0  0  0  0 -1  0  0  0  0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  1  0  0  0  0 -1  0  0  0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  1  0  0  0  0 -1  0  0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  1  0  0  0  0 -1  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  1  0  0  0  0 -1  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  1  0  0  0  0 -1  0  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  1  0  0  0  0 -1  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  1  0  0  0  0 -1  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0'
    

    编辑2:

    根据编辑后的答案,我尝试了以下代码。

    M = [
        0 0 0 0 0;
        0 1 1 1 0;
        0 1 0 1 0;
        0 1 1 1 0;
        0 0 0 0 0
    ];
    
    Mp = circshift(M, 1, 2);
    
    ind = find(M);
    indp = find(Mp.');
    
    A = zeros(25, 25);
    A(sub2ind(size(A), ind, ind)) = 1;
    A(sub2ind(size(A), ind, indp)) = -1;
    
    num2str(A(5:14, 5:14))
    

    ans =
    
      10x28 char array
    
        '0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0'
        '0  0  1 -1  0  0  0  0  0  0'
        '0  0  0  1 -1  0  0  0  0  0'
        '0  0  0  0  1 -1  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  1 -1  0'
        '0  0  0  0  0  0  0  0  0  0'
        '0  0  0  0  0  0  0  0  0  1'
    
    1 回复  |  直到 6 年前
        1
  •  3
  •   Sardar Usama    6 年前

    A 退回人 im2var(M == 1) find(M.') 无需初始化 im2var 或者只是 find(M) 自从 M 等于 transpose(M) 对你来说。 查找(M) 返回线性索引,其中 不是零而是 M A

    ind = find(M);     % ind = find(M.'); in general
    A(sub2ind(size(A),ind,ind)) = 1;
    

    附笔: 请注意,MATLAB遵循列的主要顺序,而NumPy遵循行的主要顺序。