[英]Python's scipy.sparse.csr_matrix to Matlab conversion
[英]Conversion of Matlab sparse to Python scipy csr_matrix
我對Matlab和Python都是陌生的,並且正在將一些Matlab代碼轉換為等效於Python的代碼。 我面臨的問題是從sparse(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和數據將與二維數組傳遞-尺寸的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);
...
spy(A)的第一項輸入是m(293,292)-(idx,idx + 1) ,這正是我所期望的。
spy(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
蟒蛇:
...
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);
蟒蛇:
A = A[idx,:][:,idx]
等價嗎?
非常感謝您的幫助和時間。
對我來說似乎很好,我能發現的唯一區別是:
MATLAB:
A = sparse(idx, idx+1, -D22(idx), N, N);
B = sparse(idx, idx-1, -D22(idx), N, N);
蟒蛇:
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代碼中不存在,而所有其他行都是“對稱的”
這些行令人困惑:
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向量。
您需要將第一個索引數組轉換為“列”向量以選擇一個塊(就像MATLAB版本一樣):
A[np.ix_(idx,idx+1)] # or with
A[idx[:,None],idx+1]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.