我是Matlab和Python的新手,并且正在将一些Matlab代码转换为它的Python等价物。我面临的问题是从稀疏(i,j,v,m,n)转换为 csr_matrix((data,(row_ind,col_ind)),[shape =(M, N)])即可。
在此代码中,i,j和row_in,col_ind将与索引数组一起传递 - idx 大小(124416,1),而v和数据将与2D数组一起传递 - D22 大小(290,434)
Matlab的:
...
H = 288;
W = 432;
N = (H+2)*(W+2);
mask = zeros(H+2, W+2);
mask(2:end-1, 2:end-1) = 1;
idx = find(mask==1);
>>>idx = [292, ..., 579, 582 ..., 869, ... , 125282, ..., 125569]
A = sparse(idx, idx+1, -D22(idx), N, N);
B = sparse(idx, idx-1, -D22(idx), N, N);
C = sparse(idx, idx+H+2, -D22(idx-1), N, N);
D = sparse(idx, idx-H-2, -D22(idx-1), N, N);
...
间谍(A)第一个条目是 m(293,292) - (idx,idx + 1),这是我的预期。
间谍(B) m(292,293) - (idx,idx-1)。 我期待它是m(291,292),相信idx-1将返回一个数组[291,...,578,581 ......,868,...,125281,...,125568]
间谍(C) - m(582,292) - (idx,idx + H + 2)
间谍(D) - m(292,582) - (idx,idx-H-2)
因此,鉴于我理解索引顺序,我将代码转换为Python格式
的Python:
...
H = 288
W = 432
N = (H+2) * (W+2)
mask = np.zeros([H+2, W+2])
mask[1:-1,1:-1] = 1
idx = np.nonzero(mask.transpose() == 1)
idx = np.vstack((idx[1], idx[0]))
idx = np.ravel_multi_index(idx, ((H+2),(W+2)), order='F').copy() # Linear Indexing as per Matlab
>>> idx
array([291, ..., 578, 581 ..., 868, ... , 125281, ..., 125568])
idx_ = np.unravel_index(idx, ((H+2),(W+2)), order='F') # *** Back to Linear Indexing
idx_ = np.column_stack((idx_[0], idx_[1])) # *** combine tuple of 2 arrays
idx_H_2 = np.unravel_index(idx-H-2, ((H+2),(W+2)), order='F')
idx_H_2 = np.column_stack((idx_H_2[0], idx_H_2[1]))
A = sp.csr_matrix((-D22[idx_[:,0], idx_[:,1]], (idx+1,idx)), shape = (N,N))
B = sp.csr_matrix((-D22[idx_[:,0], idx_[:,1]], (idx-1,idx)), shape = (N,N))
C = sp.csr_matrix((-D11[idx_[:,0], idx_[:,1]], (idx+H+2,idx)), shape = (N,N))
D = sp.csr_matrix((-D11[idx_H_2[:,0], idx_H_2[:,1]], (idx-H-2,idx)), shape = (N,N))
...
对于A,第一个条目是 p(292,291) - (idx + 1,idx),并且由于Python从零索引开始,它指的是Matlab m(293,292)
然而对于B,第一个条目是 p(290,291) - (idx-1,idx),这是我的预期(Matlab中的等价物应该是m(291, 292)),但如前所述,Matlab代码返回(292,293)。
C - p(581,291) - (idx + H + 2,idx)
D - p(1,291) - (idx-H-2,idx)
任何人都可以解释我可能错误理解的内容,我应该如何修改我的Python代码以更准确地反映Matlab代码。
哦,还有一个qns:)
Matlab的:
A = A(idx,idx);
的Python:
A = A[idx,:][:,idx]
是等效的吗?
非常感谢您的帮助和时间。
答案 0 :(得分:0)
对我来说似乎很好,我能发现的唯一区别是:
MATLAB:
A = sparse(idx, idx+1, -D22(idx), N, N);
B = sparse(idx, idx-1, -D22(idx), N, N);
<强>的Python:强>
A = sp.csr_matrix((-D22[idx_[:,0], idx_[:,1]], (idx+1,idx)), shape = (N,N))
B = sp.csr_matrix((-D22[idx_[:,0], idx_[:,1]], (idx,idx-1)), shape = (N,N))
请注意,在Python中,对于矩阵B,您可以沿第二维更改索引,而对于矩阵A,您可以沿第一维更改。
您的Matlab代码中不存在这种差异,而所有其他行都是“对称的”
答案 1 :(得分:0)
这些行令人困惑:
py(A) first entry is m(293, 292) - (idx,idx+1), which was what I expected.
spy(B) m(292, 293) - (idx,idx-1). I was expecting it to be m(291, 292), believing that idx-1 would return an array [291, ..., 578, 581 ..., 868, ... , 125281, ..., 125568]
spy(C) - m(582, 292) - (idx,idx+H+2)
spy(D) - m(292, 582) - (idx,idx-H-2)
什么是m(293,292)
?为什么坐标反转?这是因为spy
如何绘制轴?对于numpy代码p(...)
同样令人困惑。在我的(较小的)样本中,A
,B
等都具有非预期的非零值。
顺便问一下,D22(idx)
中有零吗?
在任何情况下,您都创建了4个稀疏矩阵,其值沿着一个对角线或其他对角线,具有周期性零间隙。
A(idx, idx+1)
与A
具有相同的非零值,但在主对角线上是连续的。
numpy代码的简明版本是:
In [159]: idx=np.where(mask.ravel()==1)[0]
In [160]: A=sparse.csr_matrix((np.ones_like(idx),(idx,idx+1)),shape=(N,N))
我忽略了F
v C
订单和D22
数组。如果我有D22
矩阵,我会尝试使用D22.ravel[idx]
(以匹配我创建和索引mask
的方式)。在比较矩阵的整体生成及其索引时,我不认为这些细节很重要。
A.tocoo().row
和A.tocoo().col
是查看非零元素的行索引和列索引的便捷方式。 A.nonzero()
也会这样做(使用几乎相同的代码)。
是的,A[idx,:][:,idx+1]
生成相同的子矩阵。
A[idx, idx+1]
给出了这些对角线值的1d向量。
您需要将第一个索引数组转换为&#39;列&#39;用于选择块的向量(如MATLAB版本所示):
A[np.ix_(idx,idx+1)] # or with
A[idx[:,None],idx+1]