2016-11-13 95 views
2

給定一個數組,我想它正常化使得每行總和爲1歸一numpy的陣列

目前,我有以下代碼:

import numpy 
w = numpy.array([[0, 1, 0, 1, 0, 0], 
       [1, 0, 0, 0, 0, 1], 
       [0, 0, 0, 0, 0, 1], 
       [1, 0, 0, 0, 1, 0], 
       [0, 0, 0, 1, 0, 1], 
       [0, 1, 1, 0, 1, 0]], dtype = float) 


def rownormalize(array): 
    i = 0 
    for row in array: 
     array[i,:] = array[i,:]/sum(row) 
     i += 1 

我有兩個問題:

1)代碼有效,但我想知道是否有更優雅的方式。

2)如何將數據類型轉換爲浮點數,如果它是int?我試過

if array.dtype == int: 
    array.dtype = float 

但它不起作用。

回答

6

你可以做1)這樣的:

array /= array.sum(axis=1, keepdims=True) 

和2)這樣的:

array = array.astype(float) 
+0

如果我添加「如果array.dtype == int:array.astype(float)」到我的函數的開始,它給了我一個零矩陣(除了一個元素是1) – wwl

+0

您需要重新分配,請參閱編輯。 – Julien

+0

如果我添加'return array'並將我的代碼更改爲'w = rownormalize(w)'而不是'rownormalize(w)',那麼該方法可行。有沒有辦法可以做到這一點,而無需做出上述改變?如果你不確定,那麼它很好 – wwl

4

部門即使broadcasted所有元素可能是昂貴的。重點對性能的替代,將預先計算行求和的倒數,並使用這些執行broadcasted乘法代替,像這樣 -

w *= 1.0/w.sum(1,keepdims=1) 

運行測試 -

In [588]: w = np.random.rand(3000,3000) 

In [589]: out1 = w/w.sum(axis=1, keepdims=True) #@Julien Bernu's soln 

In [590]: out2 = w*(1.0/w.sum(1,keepdims=1)) 

In [591]: np.allclose(out1,out2) 
Out[591]: True 

In [592]: %timeit w/w.sum(axis=1, keepdims=True) #@Julien Bernu's soln 
10 loops, best of 3: 66.7 ms per loop 

In [593]: %timeit w*(1.0/w.sum(1,keepdims=1)) 
10 loops, best of 3: 40 ms per loop 
+1

差異不是很大,但因爲它很容易完成,所以我會盡量記住這個技巧! – Julien

+0

@JulienBernu對!特別是用'broadcast',這個派上用場! – Divakar