2013-04-10 78 views
4

簡而言之:有一個similar question,最好的答案建議使用numpy.bincount。我需要同樣的東西,但對於矩陣。給定矩陣中的指數增量

我有兩個數組:

array([1, 2, 1, 1, 2]) 
array([2, 1, 1, 1, 1]) 

他們一起做應該增加指數:

>>> np.array([a, b]).T 
array([[1, 2], 
     [2, 1], 
     [1, 1], 
     [1, 1], 
     [2, 1]]) 

我想這個矩陣:

array([[0, 0, 0], 
     [0, 2, 1], # (1,1) twice, (1,2) once 
     [0, 2, 0]]) # (2,1) twice 

矩陣將會很小(如5×5),並且指數的數量會很大(大約在10^3或10^5之間)。

那麼,有沒有比for -loop更好的(更快)?

回答

3

您仍然可以使用bincount()。訣竅是將ab轉換爲單個平面索引的一維數組。

如果矩陣是n x m,您可以將bincount()應用於a * m + b,並從結果中構造矩陣。

舉的例子在你的問題:

In [15]: a = np.array([1, 2, 1, 1, 2]) 

In [16]: b = np.array([2, 1, 1, 1, 1]) 

In [17]: cnt = np.bincount(a * 3 + b) 

In [18]: cnt.resize((3, 3)) 

In [19]: cnt 
Out[19]: 
array([[0, 0, 0], 
     [0, 2, 1], 
     [0, 2, 0]]) 

如果數組的形狀比較複雜,它可能是更容易使用np.ravel_multi_index()代替手工計算平指數:

In [20]: cnt = np.bincount(np.ravel_multi_index(np.vstack((a, b)), (3, 3))) 

In [21]: np.resize(cnt, (3, 3)) 
Out[21]: 
array([[0, 0, 0], 
     [0, 2, 1], 
     [0, 2, 0]]) 

(帽尖@Jaime指出ravel_multi_index。)

+0

太棒了,謝謝! – kirelagin 2013-04-10 09:21:15

+3

+1非常好。 ['np.ravel_multi_index'](http://docs.scipy.org/doc/numpy/reference/generated/numpy.ravel_multi_index.html)可能會派上用場,避免用更復雜的數組思考太多。 – Jaime 2013-04-10 16:13:52

+0

@Jaime:太棒了,謝謝你的指針。我正在尋找'ravel_multi_index'之類的東西,但沒有找到它。 – NPE 2013-04-10 16:14:40

2
m1 = m.view(numpy.ndarray) # Create view 
m1.shape = -1 # Make one-dimensional array 
m1 += np.bincount(a+m.shape[1]*b, minlength=m1.size)