2012-04-13 35 views
22

我有以下代碼,試圖規範m x n數組的值(它將用作神經網絡的輸入,其中m是訓練示例的數量,而n是特徵的數量)。Numpy修改數組的位置?

但是,當我在腳本運行後檢查解釋器中的數組時,我發現這些值沒有正常化;也就是說,他們仍然具有原始價值。我想這是因爲函數內的變量array的賦值只能在函數內部看到。

我該如何做到這一點正常化?或者我必須從normalize函數返回一個新數組?

import numpy 

def normalize(array, imin = -1, imax = 1): 
    """I = Imin + (Imax-Imin)*(D-Dmin)/(Dmax-Dmin)""" 

    dmin = array.min() 
    dmax = array.max() 

    array = imin + (imax - imin)*(array - dmin)/(dmax - dmin) 
    print array[0] 


def main(): 

    array = numpy.loadtxt('test.csv', delimiter=',', skiprows=1) 
    for column in array.T: 
     normalize(column) 

    return array 

if __name__ == "__main__": 
    a = main() 

回答

19

如果你想數學運算適用於就地一個numpy的數組,你可以簡單地使用標準就地運營商+=-=/=等,因此,例如:

>>> def foo(a): 
...  a += 10 
... 
>>> a = numpy.arange(10) 
>>> a 
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) 
>>> foo(a) 
>>> a 
array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19]) 

在就地這些操作的版本是一個稍快一點來引導,特別是對於較大的陣列:

>>> def normalize_inplace(array, imin=-1, imax=1): 
...   dmin = array.min() 
...   dmax = array.max() 
...   array -= dmin 
...   array *= imax - imin 
...   array /= dmax - dmin 
...   array += imin 
...  
>>> def normalize_copy(array, imin=-1, imax=1): 
...   dmin = array.min() 
...   dmax = array.max() 
...   return imin + (imax - imin) * (array - dmin)/(dmax - dmin) 
... 
>>> a = numpy.arange(10000, dtype='f') 
>>> %timeit normalize_inplace(a) 
10000 loops, best of 3: 144 us per loop 
>>> %timeit normalize_copy(a) 
10000 loops, best of 3: 146 us per loop 
>>> a = numpy.arange(1000000, dtype='f') 
>>> %timeit normalize_inplace(a) 
100 loops, best of 3: 12.8 ms per loop 
>>> %timeit normalize_copy(a) 
100 loops, best of 3: 16.4 ms per loop 
+0

'%timeit'是什麼?這看起來很有趣,它是內置的嗎? – User 2012-04-14 00:28:15

+0

我在這裏使用的版本只是內置於[ipython](http://ipython.org/)。但它基於['timeit'](http://docs.python.org/library/timeit.html#module-timeit)模塊中的'timeit'函數。 – senderle 2012-04-14 00:31:22

+0

啊終於看着ipython。有趣的是,我一直把它和蟒蛇皮相關聯,現在我錯誤地看到了。 – User 2012-04-14 00:34:58

3
def normalize(array, imin = -1, imax = 1): 
    """I = Imin + (Imax-Imin)*(D-Dmin)/(Dmax-Dmin)""" 

    dmin = array.min() 
    dmax = array.max() 


    array -= dmin; 
    array *= (imax - imin) 
    array /= (dmax-dmin) 
    array += imin 

    print array[0] 
+0

性能方面是否有這樣做的問題?它與創建新陣列相比如何? – User 2012-04-13 23:40:45

+0

我的意思是,你必須進行基準測試。它取決於數組的大小。對於小問題,我肯定會創建新的數組。 – ely 2012-04-14 00:04:21

1

使用numpy時,有一種很好的方法可以進行就地規範化。當應用於數組時,與lambda函數結合使用時,np.vectorize是非常有用的。請參閱下面的示例:

import numpy as np 

def normalizeMe(value,vmin,vmax): 

    vnorm = float(value-vmin)/float(vmax-vmin) 

    return vnorm 

imin = 0 
imax = 10 
feature = np.random.randint(10, size=10) 

# Vectorize your function (only need to do it once) 
temp = np.vectorize(lambda val: normalizeMe(val,imin,imax)) 
normfeature = temp(np.asarray(feature)) 

print feature 
print normfeature 

可以將性能與生成器表達式進行比較,但可能有許多其他方法可以執行此操作。

%%timeit 
temp = np.vectorize(lambda val: normalizeMe(val,imin,imax)) 
normfeature1 = temp(np.asarray(feature)) 
10000 loops, best of 3: 25.1 µs per loop 


%%timeit 
normfeature2 = [i for i in (normalizeMe(val,imin,imax) for val in feature)] 
100000 loops, best of 3: 9.69 µs per loop 

%%timeit 
normalize(np.asarray(feature)) 
100000 loops, best of 3: 12.7 µs per loop 

因此,vectorize絕對不是最快的,但可以在性能不那麼重要的情況下傳遞。

+0

它可以完成這項工作,但是它的執行速度非常慢,因爲它像for-loop一樣實現,根據文檔。 – Michael 2016-06-07 08:38:51

+0

有沒有這種東西的基準?你會希望vectorize可以幫助它更快。 – user48956 2017-08-29 03:55:06

0

這是一種技巧,它比其他有用的答案在這裏稍微一般:

def normalize(array, imin = -1, imax = 1): 
    """I = Imin + (Imax-Imin)*(D-Dmin)/(Dmax-Dmin)""" 

    dmin = array.min() 
    dmax = array.max() 

    array[...] = imin + (imax - imin)*(array - dmin)/(dmax - dmin) 

在這裏,我們的觀點array[...]分配值,而不是範圍內分配這些值來一些新的局部變量的功能。

x = np.arange(5, dtype='float') 
print x 
normalize(x) 
print x 

>>> [0. 1. 2. 3. 4.] 
>>> [-1. -0.5 0. 0.5 1. ]