2017-06-12 84 views
3

我是python的新手,面臨處理矩陣的問題。在Python中處理矩陣

我有一個矩陣,讓我們說

A = [1 0 0 2; 3 3 3 2; 3 3 0 2; 3 4 4 4] 

現在,我想在矩陣等於零的所有元素,但它們在重複矩陣的最大次數的元素。 (在這種情況下,它是3)。

因此,預期的結果是,

B = [0 0 0 0; 3 3 3 0; 3 3 0 0;3 0 0 0] 

這將是非常有益的,如果有人能幫助我與此Python代碼。

回答

1

這是MATLAB語法,不是numpy:

A = [1 0 0 2; 3 3 3 2; 3 3 0 2; 3 4 4 4] 

雖然np.matrix與模擬它:

In [172]: A = np.matrix('1 0 0 2; 3 3 3 2; 3 3 0 2; 3 4 4 4') 
In [173]: A 
Out[173]: 
matrix([[1, 0, 0, 2], 
     [3, 3, 3, 2], 
     [3, 3, 0, 2], 
     [3, 4, 4, 4]]) 

你的任務是2倍,這一發現最常見的元素,然後更換所有的人。這兩種行爲都不依賴於矩陣是2d,或者是matrix而不是陣列。

In [174]: A1=A.A1 
In [175]: A1 
Out[175]: array([1, 0, 0, 2, 3, 3, 3, 2, 3, 3, 0, 2, 3, 4, 4, 4]) 

np.unique可以給我們的頻率計數,所以我們可以細跟最頻繁的值(unique需要1D):

In [179]: u,c = np.unique(A1, return_counts=True) 
In [180]: u 
Out[180]: array([0, 1, 2, 3, 4]) 
In [181]: c 
Out[181]: array([3, 1, 3, 6, 3]) 
In [182]: np.argmax(c) 
Out[182]: 3 
In [183]: u[np.argmax(c)] 
Out[183]: 3 

我很驚訝,Divakar使用scipymode代替unique。他是使用unique的專家。 :)

Divakar使用np.where可能是執行替換的最簡單方法。

只爲它的樂趣,這裏有一個屏蔽數組的方法:

In [196]: np.ma.MaskedArray(A, A!=3) 
Out[196]: 
masked_matrix(data = 
[[-- -- -- --] 
[3 3 3 --] 
[3 3 -- --] 
[3 -- -- --]], 
       mask = 
[[ True True True True] 
[False False False True] 
[False False True True] 
[False True True True]], 
     fill_value = 999999) 
In [197]: _.filled(0) 
Out[197]: 
matrix([[0, 0, 0, 0], 
     [3, 3, 3, 0], 
     [3, 3, 0, 0], 
     [3, 0, 0, 0]]) 

或就地變化:

In [199]: A[A!=3] = 0 
In [200]: A 
Out[200]: 
matrix([[0, 0, 0, 0], 
     [3, 3, 3, 0], 
     [3, 3, 0, 0], 
     [3, 0, 0, 0]]) 
+0

良好的通話'np.unique',堅持NumPy的! – Divakar

+0

謝謝hpaulj,這非常有幫助。我一直在使用Matlab,並決定我也應該嘗試Python。感謝您的支持。 –

2

使用Scipy's modeaxis設置爲None獲取整個陣列中出現次數最多的數字。將該數字與輸入數組進行比較,以給我們一個掩碼,通過與輸入數組/最多出現的數字進行元素相乘或使用np.where進行選擇,可將掩碼設置爲零。

因此,一種方法是 -

from scipy.stats import mode 

most_occ_num = mode(A, axis=None)[0][0] 
out = most_occ_num*(A==most_occ_num) 

隨着np.where爲陣列輸出 -

out = np.where(A==most_occ_num,A,0) 

樣品運行 -

In [129]: A = np.matrix([[1, 0 ,0 ,2],[ 3, 3, 3, 2],[ 3 ,3 ,0 ,2],[ 3 ,4 ,4 ,4]]) 
In [140]: A 
Out[140]: 
matrix([[1, 0, 0, 2], 
     [3, 3, 3, 2], 
     [3, 3, 0, 2], 
     [3, 4, 4, 4]]) 

In [141]: most_occ_num = mode(A, axis=None)[0][0] 

In [142]: most_occ_num*(A==most_occ_num) 
Out[142]: 
matrix([[0, 0, 0, 0], 
     [3, 3, 3, 0], 
     [3, 3, 0, 0], 
     [3, 0, 0, 0]]) 

In [143]: np.where(A==most_occ_num,A,0) 
Out[143]: 
array([[0, 0, 0, 0], 
     [3, 3, 3, 0], 
     [3, 3, 0, 0], 
     [3, 0, 0, 0]]) 
1

甲純Python的方法:

counts = [[x.count(i) for i in x] for x in A] 
B = [[n if x.count(n) == max(counts[i]) else 0 for n in x ] for (i, x) in enumerate(A)] 
0

首先,壓平:

flat = A.flatten[0] 
# flat = [1, 0, 0, 2, .. ] 

然後,找到列表模式:

Finding the mode of a list

更換無模式:

B = A.copy() 
B[B != mode] = 0