numpy

2014-12-19 10 views
6

के साथ पुनरावृत्ति गणना को सदिश करने की कोशिश कर रहा हूं मैं संख्या में वेक्टरकृत रूप का उपयोग करके कोड का कुछ टुकड़ा अधिक कुशल बनाने की कोशिश कर रहा हूं। मुझे आपको एक उदाहरण दिखाएं ताकि आप जान सकें कि मेरा क्या मतलब है।numpy

को देखते हुए निम्नलिखित कोड:

a = np.zeros([4,4]) 
a[0] = [1., 2., 3., 4.] 
for i in range(len(a)-1): 
    a[i+1] = 2*a[i] 
print a 

यह आउटपुट

[[ 1. 2. 3. 4.] 
[ 2. 4. 6. 8.] 
[ 4. 8. 12. 16.] 
[ 8. 16. 24. 32.]] 

जब मैं अब इस तरह कोड vectorize करने की कोशिश:

a = np.zeros([4,4]) 
a[0] = [1., 2., 3., 4.] 
a[1:] = 2*a[0:-1] 
print a 

मैं सिर्फ पहली यात्रा ठीक से पता होना :

[[ 1. 2. 3. 4.] 
[ 2. 4. 6. 8.] 
[ 0. 0. 0. 0.] 
[ 0. 0. 0. 0.]] 

क्या वेक्टरेटेड फॉर्म में कुशलता से ऊपर कोड लिखना संभव है (जहां अगला पुनरावृत्ति हमेशा पिछले पुनरावृत्ति तक पहुंचता है) या क्या मुझे for लूप रखना है?

उत्तर

5

एक रेखीय पुनरावृत्ति जैसे यह गणना की जा सकती scipy.signal.lfilter का उपयोग कर प्राप्त कर सकते हैं:

In [19]: from scipy.signal import lfilter 

In [20]: num = np.array([1.0]) 

In [21]: alpha = 2.0 

In [22]: den = np.array([1.0, -alpha]) 

In [23]: a = np.zeros((4,4)) 

In [24]: a[0,:] = [1,2,3,4] 

In [25]: lfilter(num, den, a, axis=0) 
Out[25]: 
array([[ 1., 2., 3., 4.], 
     [ 2., 4., 6., 8.], 
     [ 4., 8., 12., 16.], 
     [ 8., 16., 24., 32.]]) 

अधिक जानकारी के लिए निम्न देखें: python recursive vectorization with timeseries, Recursive definitions in Pandas


ध्यान दें कि lfilter का उपयोग कर वास्तव में केवल समझ में आता है अगर आप एक nonhomogeneous समस्या को हल करते हैं x[i+1] = alpha*x[i] + u[i] जैसे लीम, जहां u एक दिया इनपुट सरणी है। सरल पुनरावृत्ति a[i+1] = alpha*a[i] के लिए, आप सटीक समाधान a[i] = a[0]*alpha**i का उपयोग कर सकते हैं। कई शुरुआती मूल्यों के समाधान को प्रसारण का उपयोग करके वेक्टरकृत किया जा सकता है।(ELEM वार) उदाहरण के लिए,

In [271]: alpha = 2.0 

In [272]: a0 = np.array([1, 2, 3, 4]) 

In [273]: n = 5 

In [274]: a0 * (alpha**np.arange(n).reshape(-1, 1)) 
Out[274]: 
array([[ 1., 2., 3., 4.], 
     [ 2., 4., 6., 8.], 
     [ 4., 8., 12., 16.], 
     [ 8., 16., 24., 32.], 
     [ 16., 32., 48., 64.]]) 
4

Numpy के सदिश गणना चरणों का क्रम के रूप में नहीं, वेक्टर पर कार्रवाई है, तो आप पूरे अभिव्यक्ति vectorize करने के लिए है। उदाहरण के लिए:

np.multiply(np.arange(1,5), 2**np.arange(0,4)[np.newaxis].T) 

"अंतिम" प्रश्न को हल करने के लिए, हाँ आप for पाश रखने के लिए यदि आप एक अनुक्रमिक गणना करने के लिए चाहते हैं। आप map या [... for ...] के साथ इसे और अधिक कुशल बना सकते हैं लेकिन इस तरह अनुकूलित करने से बहुत सारे परीक्षण और त्रुटि होती है। वेक्टरियल शब्दों में सोचने की सुंदरता और लागू करने के लिए नम्पी का उपयोग करना यह है कि आपको सभी परीक्षण और त्रुटि के बिना परिणाम मिलते हैं।

cumsum और cumprod फ़ंक्शंस आप जो भी मांग रहे हैं उसके समान कुछ कर सकते हैं। 2**np.arange(...) के बजाय, आप एक ही बात से

np.multiply(np.arange(1,5), np.cumprod([1,2,2,2,])[np.newaxis].T) 
0

अपने परिणाम मैट्रिक्स

result = [[ 1, 2, 3, 4,] 
      [ 2, 4, 6, 8,] 
      [ 4, 8, 12, 16,] 
      [ 8, 16, 24, 32,]] 

को देखकर यह उत्पाद में deconstructed जा सकता है की दो के रूप में मैट्रिक्स

a = [[1, 2, 3, 4], 
    [1, 2, 3, 4], 
    [1, 2, 3, 4], 
    [1, 2, 3, 4]] 

b = [[1, 1, 1, 1], 
    [2, 2, 2, 2], 
    [4, 4, 4, 4] 
    [8, 8, 8, 8]] 

result = a * b 

आप इस प्रकार की गणना कर सकते हैं meshgrid समारोह

aa, bb = np.meshgrid(np.array([1.0, 2.0, 3.0, 4.0]), 
        np.array([1.0, 2.0, 4.0, 8.0])) 
result = aa * bb 
का उपयोग कर आपरेशन