2011-08-07 15 views
5

मैं कुछ डेटा विश्लेषण करने के लिए पाइथन और न्यूम्पी का उपयोग कर रहा हूं।3 डी सरणी पर कुशल पुनरावृत्ति?

मेरे पास एक बड़ा 3 डी मैट्रिक्स (एनएक्सएनएक्सएन) है, जहां प्रत्येक सेल फिर से एक मैट्रिक्स है, इस बार एक 3x3 मैट्रिक्स है। मैट्रिक्स data कॉलिंग, यह इस तरह दिखता है:

data[N,N,N,3,3] 

मैं सभी 3x3 eigenvalues ​​के matrices खोजने की जरूरत है, और उस के लिए मैं Numpy के eigvals नियमित उपयोग करें, लेकिन यह करने के लिए उम्र ले जाता है। अभी मैं इसे बहुत अधिक करता हूं:

for i in range(N): 
    for j in range(N): 
     for k in range(N): 
      a = np.linalg.eigvals(data[i,j,k,:,:]) 

एन = 256 के लिए, इसमें लगभग एक घंटे लगते हैं। इसे और अधिक कुशल बनाने के तरीके पर कोई विचार?

किसी भी सुझाव के लिए बहुत धन्यवाद!

+4

क्या आपने प्रोफाइल किया है? मुझे संदेह है कि आप इगर्वल्स में ज्यादा समय बिता रहे हैं जितना आप पुनरावृत्त कर रहे हैं। – matt

+3

eigvals मेरी टाइमिट गणनाओं द्वारा लंबे समय तक परिमाण के लगभग तीन आदेश लेता है, इसलिए मुझे नहीं लगता कि पुनरावृत्ति को बदलने से कुछ भी प्रभावित हो रहा है। – DSM

उत्तर

5

itertools.product नेस्टेड छोरों से अच्छे है, सौंदर्य की दृष्टि से बोल रहा है। लेकिन मुझे नहीं लगता कि यह आपके कोड को बहुत तेज़ कर देगा। मेरा परीक्षण बताता है कि पुनरावृत्ति आपकी बाधा नहीं है।

>>> bigdata = numpy.arange(256 * 256 * 256 * 3 * 3).reshape(256, 256, 256, 3, 3) 
>>> %timeit numpy.linalg.eigvals(bigdata[100, 100, 100, :, :]) 
10000 loops, best of 3: 52.6 us per loop 

तो underestimating:

>>> .000052 * 256 * 256 * 256/60 
14.540253866666665 

अपने कंप्यूटर, जो बहुत नया है पर 14 मिनट के न्यूनतम है यही कारण है कि। चलो देखते हैं कि लूप कितने समय लेते हैं ...

>>> def just_loops(N): 
...  for i in xrange(N): 
...   for j in xrange(N): 
...    for k in xrange(N): 
...     pass 
... 
>>> %timeit just_loops(256) 
1 loops, best of 3: 350 ms per loop 

आयाम के आदेश छोटे, जैसा कि डीएसएम ने कहा। यहां तक ​​कि सरणी अकेले टुकड़ा करने की क्रिया का काम अधिक पर्याप्त है:

>>> def slice_loops(N, data): 
...  for i in xrange(N): 
...   for j in xrange(N): 
...    for k in xrange(N): 
...     data[i, j, k, :, :] 
... 
>>> %timeit slice_loops(256, bigdata) 
1 loops, best of 3: 33.5 s per loop 
+0

बहुत गहन जवाब के लिए धन्यवाद! आपके परीक्षणों से यह वास्तव में ऐसा लगता है कि इसे तेज़ी से बनाने के लिए बहुत कुछ नहीं किया जाना चाहिए। – digitaldingo

3

मुझे यकीन है कि NumPy में ऐसा करने का एक अच्छा तरीका है, लेकिन सामान्य रूप से, itertools.product सीमाओं पर नेस्टेड लूप से तेज़ है।

from itertools import product 

for i, j, k in product(xrange(N), xrange(N), xrange(N)): 
    a = np.linalg.eigvals(data[i,j,k,:,:]) 
+0

इस मामले में - चूंकि एन इतना छोटा है - मुझे वास्तव में पता चलता है कि लूप ओवरहेड उत्पाद लूप के साथ मोटे तौर पर दो गुना अधिक है, जो घोंसले वाली श्रेणियों के साथ है। मुझे अभी भी उत्पाद दृष्टिकोण बेहतर पसंद है, क्योंकि यह चापलूसी है और वैसे भी ओवरहेड नगण्य है। – DSM

+0

यह दिलचस्प है। मुझे लगता है कि 65536 + 256 आंतरिक सूचियां धीमी हो जाएंगी (हालांकि मुझे उम्मीद नहीं थी कि यह एक बड़ा अंतर करे)। – agf

2

के बाद से सभी गणना स्वतंत्र हैं, आप अगर आप एक मल्टी कोर प्रोसेसर गणना तेजी लाने के लिए बहु मॉड्यूल का उपयोग कर सकते हैं।