2012-04-13 15 views
22

मेरे पास निम्न कोड है जो m x n सरणी के मानों को सामान्य करने का प्रयास कर रहा है (इसे एक तंत्रिका नेटवर्क में इनपुट के रूप में उपयोग किया जाएगा, जहां m प्रशिक्षण उदाहरणों की संख्या है और n सुविधाओं की संख्या है)।जगह में अजीब संशोधित सरणी?

हालांकि, जब मैं दुभाषिया में सरणी का निरीक्षण करने के बाद स्क्रिप्ट चलाता है, मुझे लगता है कि मानों सामान्यीकृत नहीं हैं; यही है, उनके पास अभी भी मूल मूल्य हैं। मुझे लगता है कि ऐसा इसलिए है क्योंकि फ़ंक्शन के अंदर array चर के लिए असाइनमेंट केवल फ़ंक्शन के भीतर देखा जाता है।

मैं जगह में इस सामान्य कैसे कर सकता है? या क्या मुझे सामान्यीकृत फ़ंक्शन से एक नई सरणी वापस करनी है?

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

+0

संस्करण मैं यहाँ का उपयोग केवल [IPython] करने के लिए बनाया गया है (http://ipython.org/)। लेकिन यह '[' timeit'] (http://docs.python.org/library/timeit.html#module-timeit) मॉड्यूल में timeit' समारोह पर आधारित है। – senderle

+0

आह अंततः ipython पर देखा। मजेदार मैं हमेशा इसे ironpython से जुड़ा हुआ था, गलती से अब मैं देखता हूँ। – User

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

+0

मेरा मतलब है, इसके लिए आपको बेंचमार्क करना होगा। यह सरणी के आकार पर निर्भर करता है। छोटी-छोटी समस्याओं के लिए, मैं निश्चित रूप से केवल नई सरणी बनाउंगा। – ely

1

जब numpy का उपयोग करने में जगह सामान्य करने के लिए एक अच्छा तरीका है। np.vectorize बहुत उपयोगी है जब जब एक सरणी के लिए लागू एक lambda समारोह के साथ संयुक्त है। नीचे दिए गए उदाहरण देखें:

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 

तो वेक्टरिज निश्चित रूप से सबसे तेज़ नहीं है, लेकिन ऐसे मामलों में संगत हो सकता है जहां प्रदर्शन उतना महत्वपूर्ण नहीं है।

+0

यह नौकरी करता है, लेकिन यह बहुत धीमा है क्योंकि इसे प्रलेखन के अनुसार, फॉर-लूप की तरह लागू किया गया है। – Michael

+0

क्या इस तरह की चीज के लिए कोई बेंचमार्क है? आप उम्मीद करेंगे कि वेक्टरिज़ इसे बहुत तेजी से जाने में मदद कर सकता है। – user48956

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. ] 
संबंधित मुद्दे