2010-12-21 9 views
9

numpy vectorize फ़ंक्शन उपयोगी है, लेकिन जब फ़ंक्शन तर्क सूचियों के बजाय सूचियां होती हैं तो यह अच्छी तरह से व्यवहार नहीं करती है। एक उदाहरण के रूप:गैर-वेक्टरटाइज, सूचियों का उपयोग तर्कों के रूप में

import numpy as np 

def f(x, A): 
    print "type(A)=%s, A=%s"%(type(A),A) 
    return sum(A)/x 

X = np.linspace(1,2,10) 
P = [1,2,3] 

f2 = np.vectorize(f) 

f(X,P) 
f2(X,P) 

देता है:

type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'numpy.int64'>, A=1 

Traceback (most recent call last): 
    File "vectorize.py", line 14, in <module> 
    f2(X,P) 
    File "/usr/local/lib/python2.6/dist-packages/numpy/lib/function_base.py", line 1824, in __call__ 
    theout = self.thefunc(*newargs) 
    File "vectorize.py", line 5, in f 
    return sum(A)/x 
TypeError: 'numpy.int64' object is not iterable 

मैं समझता हूँ कि समारोह च vectorize बिना ठीक काम करता है यह ing, लेकिन मुझे पता है कि कैसे करने के लिए (सामान्य रूप में) vectorize करना चाहते हैं एक फ़ंक्शन जिसका तर्क स्केलर की बजाय सूचियों में लेता है।

उत्तर

11

आपका प्रश्न स्पष्ट रूप से स्पष्ट नहीं करता है कि आप वेक्टरेटेड फ़ंक्शन से कौन सा आउटपुट देखना चाहते हैं, लेकिन मुझे लगता है कि आप एक ही सूची (ए) को एफ के प्रत्येक आमंत्रण के लिए तर्क के रूप में लागू करना चाहते हैं () (यानी एक्स सरणी में प्रत्येक तत्व के लिए)

फ़ंक्शन का वेक्टरिज्ड संस्करण सुनिश्चित करता है कि सभी तर्क सरणी हैं, और फिर यह निर्धारित करने के लिए numpy's broadcasting rules लागू होता है कि इन तर्कों को कैसे जोड़ा जाना चाहिए।

np.ndarray की np.array के रैपिंग के साथ के रूप में, सरणियों पर तर्कों की बलात्कार, सहायक हो स्वचालित रूप से एक सरणी के लिए एक सूची परिवर्तित एक ही तत्वों से युक्त है, बजाय dtype = वस्तु के साथ एक सरणी बनाने के द्वारा की कोशिश करता है सूची को एकमात्र तत्व के रूप में शामिल किया गया है। अधिकांश समय हम यही चाहते हैं, लेकिन आपके मामले में, यह "स्मार्ट" व्यवहार आपको काटने के लिए वापस आ रहा है।

केवल करने के लिए numpy निर्देश देने के लिए एक तरह से वहाँ हो सकता है, वैक्टर के रूप में कुछ आदानों का इलाज वहाँ व्यवहार आप के बाद कर रहे हैं पाने के लिए दो सरल तरीके हैं:

  1. मैन्युअल प्रसारण के भीतर काम करने के लिए एक array with dtype=object बनाने नियम
  2. Curry समारोह vectorizing

1. dtype = वस्तु

012,351,641 से पहले मूल्य

NumPy सरणी केवल आइटम का एक प्रकार संग्रहीत करने से उनकी दक्षता प्राप्त है, लेकिन वे अभी भी निर्दिष्ट करना संग्रहीत डेटा प्रकार अजगर वस्तुओं होना द्वारा मनमाने ढंग से अजगर वस्तुओं को शामिल कर सकते हैं:

list_obj_array = np.ndarray((1,), dtype=object) 
list_obj_array[0] = [1,2,3] 
f2(X,list_obj_array) # using your definition from above 

प्रिंट:

type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 

और रिटर्न:

array([ 6.  , 5.4  , 4.90909091, 4.5  , 4.15384615, 
     3.85714286, 3.6  , 3.375  , 3.17647059, 3.  ]) 

2।

def curry_f(A): 
    def f_curried(x): 
     return f(x, A) # using your definition from above 
    return f_curried 

f2 = np.vectorize(curry_f(P)) 
f2(X) 

प्रिंट:

Currying जब से तुम सरणी में प्रत्येक आइटम के लिए समारोह कॉल करने के लिए एक ही सूची से गुजर रहे हैं, तो आप सूची सीधे समारोह के साथ लागू करने के vectorization से पहले currying से स्टोर कर सकते हैं

type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 
type(A)=<type 'list'>, A=[1, 2, 3] 

और रिटर्न:

array([ 6.  , 5.4  , 4.90909091, 4.5  , 4.15384615, 
     3.85714286, 3.6  , 3.375  , 3.17647059, 3.  ]) 

पीएस आप np.frompyfunc पर भी देखना चाहते हैं - यह vectorize() के समान है, लेकिन थोड़ा कम स्तर पर काम करता है।

0

यह एक पुनरावर्ती डेकोरेटर मैं वर्तमान में एक समारोह है कि पहले तर्क के रूप में एक 1 डी सरणी लेता vectorize करने के लिए उपयोग कर रहा हूँ का एक उदाहरण है:,

def broadcast(fvec): 
    def inner(vec, *args, **kwargs): 
     if len(vec.shape) > 1: 
      return np.array([inner(row, *args, **kwargs) for row in vec]) 
     else: 
      return fvec(vec, *args, **kwargs) 
    return inner 

मैं यह बहुत ज्यादा एक ही np.vectorize के रूप में करता है लगता है लेकिन नौकरी के लिए vectorize/frompyfunc को अनुकूलित करने की कोशिश करने के लिए इसका उपयोग करना मेरे लिए आसान हो गया।

संबंधित मुद्दे