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

Python 使用掩码的逻辑索引在numpy中工作,而不是在Matlab中,python,matlab,numpy,matrix-indexing,Python,Matlab,Numpy,Matrix Indexing,我试图在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],

我试图在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'
谢谢你的帮助

编辑:我也想实现以下效果,但当前的答案似乎不适用于两组索引

在Python中:

>>> 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)
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))
虽然对角线1已成功显示,但-1位于错误的位置

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)
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))
但它仍然不能产生与edit1中的Python代码相同的结果

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'

在MATLAB中,您可以获得由目标位置的
im2var(M==1)
返回的
A
的相关行和列下标。这也可以通过
find(M.)
来完成,而无需初始化
im2var
或只需
find(M)
,因为在您的情况下
M
等于
transpose(M)
find(M)
返回线性索引,其中
M
不是零,但是
M
的线性索引与
A
的行和列下标相同。您不能直接使用这些行和列下标,需要将它们转换为线性索引,然后继续,即

ind=find(M);%ind=查找(M.);一般来说
A(sub2ind(size(A),ind,ind))=1;

p.S:请注意,MATLAB遵循列主顺序,而NumPy遵循行主顺序。

在MATLAB中,您可以获得目标位置的
im2var(M==1)
返回的
A
的相关行和列下标。这也可以通过
find(M.)
来完成,而无需初始化
im2var
或只需
find(M)
,因为在您的情况下
M
等于
transpose(M)
find(M)
返回线性索引,其中
M
不是零,但是
M
的线性索引与
A
的行和列下标相同。您不能直接使用这些行和列下标,需要将它们转换为线性索引,然后继续,即

ind=find(M);%ind=查找(M.);一般来说
A(sub2ind(size(A),ind,ind))=1;

p.S:请注意,MATLAB遵循列主顺序,而NumPy遵循行主顺序。

非常感谢!这当然适用于相同的索引情况。我已经更新了我的问题,对两组指数进行了概括。从你原来的问题开始,似乎M和Mᵗ 都是一样的。我已经编辑了答案来纠正这个问题。是的,我确实忘记了最初提到的
Mp
-对不起!我尝试了你的编辑,但仍然不起作用。@fuzz为了回答这个问题,
A(6:15,6:15)
是你期望的结果;不是
A(5:14,5:14)
。在MATLAB中,索引从1开始,而不是从零开始。使用冒号操作符,两个边界都包含在MATLAB中。在使用该功能之前,请参阅文档。MATLAB和NumPy不是一对一兼容的,太感谢你了!这当然适用于相同的索引情况。我已经更新了我的问题,对两组指数进行了概括。从你原来的问题开始,似乎M和Mᵗ 都是一样的。我已经编辑了答案来纠正这个问题。是的,我确实忘记了最初提到的
Mp
-对不起!我尝试了你的编辑,但仍然不起作用。@fuzz为了回答这个问题,
A(6:15,6:15)
是你期望的结果;不是
A(5:14,5:14)
。在MATLAB中,索引从1开始,而不是从零开始。使用冒号操作符,两个边界都包含在MATLAB中。在使用该功能之前,请参阅文档。MATLAB和NumPy不是一对一兼容的Enumpy使用基于0的索引,但MATLAB使用基于1的索引。考虑使用NoPy的文档使用基于0的索引,但是Matlab使用基于1的索引。考虑阅读文档。