簡體   English   中英

Matlab稀疏到Python scipy csr_matrix的轉換

[英]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(...)同樣令人困惑。 在我的(較小的)樣本中, AB等在我期望的位置都具有非零值。

順便說一句, 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().rowA.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM