2015-10-28 6 views
12

पर 'आउट' तर्क के रूप में अजीब गुजरने वाली इनपुट सरणी को आम तौर पर इनपुट सरणी को वैकल्पिक रूप से एक यूफुनक में वैकल्पिक आउट तर्क के रूप में प्रदान करने के लिए सुरक्षित है, बशर्ते कि यह सही है? उदाहरण के लिए, मैं पुष्टि कर लें कि निम्न काम करता है:यूफुन

>>> import numpy as np 
>>> arr = np.array([1.2, 3.4, 4.5]) 
>>> np.floor(arr, arr) 
array([ 1., 3., 4.]) 

सरणी प्रकार या तो संगत या निर्गम (जो numpy.floor() के लिए एक नाव है) के साथ समान होना चाहिए, या ऐसा होता है:

>>> arr2 = np.array([1, 3, 4], dtype = np.uint8) 
>>> np.floor(arr2, arr2) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: ufunc 'floor' output (typecode 'e') could not be coerced to provided output parameter (typecode 'B') according to the casting rule ''same_kind'' 

तो उचित प्रकार की एक सरणी दी गई है, क्या यह आमतौर पर ufuncs को लागू करने के लिए सुरक्षित है? या floor() एक असाधारण मामला है? प्रलेखन यह स्पष्ट नहीं है, और न तो निम्न दो धागे सवाल पर स्पर्शरेखा प्रभाव पड़ता है कार्य करें:

  1. Numpy modify array in place?
  2. Numpy Ceil and Floor "out" Argument

संपादित करें:

एक के रूप में पहला ऑर्डर अनुमान है, मुझे लगता है कि http://docs.scipy.org/doc/numpy/user/c-info.ufunc-tutorial.html पर ट्यूटोरियल के आधार पर यह अक्सर होता है, लेकिन हमेशा सुरक्षित नहीं होता है। गणना के दौरान इंटरमीडिएट परिणामों के लिए अस्थायी धारक के रूप में आउटपुट सरणी का उपयोग करने पर कोई प्रतिबंध नहीं दिखता है। जबकि floor() और ciel() जैसे कुछ अस्थायी भंडारण की आवश्यकता नहीं हो सकती है, अधिक जटिल कार्य हो सकते हैं। कहा जा रहा है कि, मौजूदा मौजूदा पुस्तकालय को इसके साथ दिमाग में लिखा जा सकता है।

+2

यह तकनीकी रूप से एक ufunc नहीं है, लेकिन इस तरह से 'np.dot' में' आउट' पैरामीटर का उपयोग करके 2 डी arrays गलत परिणाम उत्पन्न कर सकते हैं। –

+0

यह लगभग काउंटररेक्स नमूना है जिसे मैं ढूंढ रहा था, लेकिन काफी नहीं :) –

+3

[ufunc दस्तावेज़] (http://docs.scipy.org/doc/numpy/reference/ufuncs.html) 'ऐड (जी, सी, जी) 'गणित परिचालन "के तहत युक्ति में' जी = जी + सी 'के अनुकूलन के रूप में। मैं कहूंगा कि यह सुरक्षित है। (दूसरी ओर, इनपुट और आउटपुट ओवरलैपिंग के साथ ufuncs को कॉल करना, लेकिन समान नहीं * * समस्याएं पैदा करेगा।) – user2357112

उत्तर

2

out एक numpy फ़ंक्शन का पैरामीटर वह सरणी है जहां परिणाम लिखा गया है। out का उपयोग करने का मुख्य लाभ नई स्मृति के आवंटन से परहेज करता है जहां यह आवश्यक नहीं है।

क्या इनपुट के रूप में पारित उसी सरणी पर फ़ंक्शन के आउटपुट को लिखना सुरक्षित है? कोई सामान्य जवाब नहीं है, यह इस बात पर निर्भर करता है कि समारोह क्या कर रहा है।

In [1]: def plus_one(x, out=None): 
    ...:  if out is None: 
    ...:   out = np.zeros_like(x) 
    ...: 
    ...:  for i in range(x.size): 
    ...:   out[i] = x[i] + 1 
    ...:  return out 
    ...: 

In [2]: x = np.arange(5) 

In [3]: x 
Out[3]: array([0, 1, 2, 3, 4]) 

In [4]: y = plus_one(x) 

In [5]: y 
Out[5]: array([1, 2, 3, 4, 5]) 

In [6]: z = plus_one(x, x) 

In [7]: z 
Out[7]: array([1, 2, 3, 4, 5]) 

समारोह shift_one:

दो उदाहरण

यहाँ ufunc-जैसे कार्यों के दो उदाहरण हैं

In [11]: def shift_one(x, out=None): 
    ...:  if out is None: 
    ...:   out = np.zeros_like(x) 
    ...: 
    ...:  n = x.size 
    ...:  for i in range(n): 
    ...:   out[(i+1) % n] = x[i] 
    ...:  return out 
    ...: 

In [12]: x = np.arange(5) 

In [13]: x 
Out[13]: array([0, 1, 2, 3, 4]) 

In [14]: y = shift_one(x) 

In [15]: y 
Out[15]: array([4, 0, 1, 2, 3]) 

In [16]: z = shift_one(x, x) 

In [17]: z 
Out[17]: array([0, 0, 0, 0, 0]) 

समारोह plus_one के लिए वहाँ कोई समस्या नहीं है: अपेक्षित परिणाम है जब पैरामीटर एक्स और आउट एक ही सरणी होते हैं तो प्राप्त किया जाता है। लेकिन समारोह shift_one एक आश्चर्यजनक परिणाम देता है जब पैरामीटर एक्स और बाहर एक ही सरणी हैं, क्योंकि सरणी

चर्चा

रूप out[i] := some_operation(x[i]) के समारोह के लिए, ऊपर, लेकिन यह भी काम करता है मंजिल, प्लस्तर लगाना, पाप जैसे plus_one , cos, tan, log, conj, आदि, जहां तक ​​मुझे पता है कि यह सुरक्षित पैरामीटर आउटपुट का उपयोग करके इनपुट में परिणाम लिखने के लिए है। = Some_operation (एक्स [i], वाई [i]) इस तरह के numpy समारोह, जोड़ने गुणा, घटाना के रूप में:

यह भी सुरक्षित प्रपत्र `` बाहर [i] के दो इनपुट पैरामीटर लेने कार्यों के लिए है।

अन्य कार्यों के लिए, यह मामला-दर-मामला है। सचित्र bellow के रूप में, आव्यूह गुणन सुरक्षित नहीं है:

In [18]: a = np.arange(4).reshape((2,2)) 

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

In [20]: b = (np.arange(4) % 2).reshape((2,2)) 

In [21]: b 
Out[21]: 
array([[0, 1], 
     [0, 1]], dtype=int32) 

In [22]: c = np.dot(a, b) 

In [23]: c 
Out[23]: 
array([[0, 1], 
     [0, 5]]) 

In [24]: d = np.dot(a, b, out=a) 

In [25]: d 
Out[25]: 
array([[0, 1], 
     [0, 3]]) 

अंतिम टिप्पणी: अगर कार्यान्वयन थ्रेड है, एक असुरक्षित फ़ंक्शन के परिणाम भी गैर नियतात्मक हो सकता है, क्योंकि यह आदेश पर निर्भर करता है, जिस पर सरणी तत्व संसाधित कर रहे हैं।