2016-04-25 6 views
6

मैं बिना हस्ताक्षर किए 32 बिट इन्स की बड़ी संख्या (कई गीगाबाइट) स्टोर करने के लिए सरणी मॉड्यूल का उपयोग कर रहा हूं। प्रत्येक तत्व के लिए 4 बाइट्स का उपयोग करने के बजाय, अजगर 8 बाइट्स का उपयोग कर रहा है, जैसा कि array.itemsize द्वारा इंगित किया गया है, और pympler द्वारा सत्यापित किया गया है।क्या मैं पाइथन सरणी तत्वों को एक विशिष्ट आकार के लिए मजबूर कर सकता हूं?

जैसे:

>>> array("L", range(10)).itemsize 
8 

मैं तत्वों की एक बड़ी संख्या है, इसलिए मैं 4 बाइट के भीतर उन्हें संग्रहीत करने से लाभ होगा।

Numpy मुझे अहस्ताक्षरित 32 बिट ints के रूप में मान संग्रहीत करने देगा:

>>> np.array(range(10), dtype = np.uint32).itemsize 
4 

लेकिन समस्या यह है कि numpy के सूचकांक ऑपरेटर का उपयोग किसी भी आपरेशन है के बारे में दो बार के रूप में धीमी गति से, इसलिए कार्य है कि वेक्टर संचालन नहीं कर रहे हैं समर्थित numpy द्वारा धीमी हैं। जैसे:

python3 -m timeit -s "from array import array; a = array('L', range(1000))" "for i in range(len(a)): a[i]" 
10000 loops, best of 3: 51.4 usec per loop 

बनाम

python3 -m timeit -s "import numpy as np; a = np.array(range(1000), dtype = np.uint32)" "for i in range(len(a)): a[i]" 
10000 loops, best of 3: 90.4 usec per loop 

तो मैं करने के लिए मजबूर कर रहा हूँ या तो दुगनी हो जाती स्मृति का उपयोग के रूप में मैं चाहूँगा, या कार्यक्रम दो बार के रूप में धीमी गति से के रूप में मैं चाहूँगा चलेंगे। क्या इसके चारों ओर एक रास्ता है? क्या मैं निर्दिष्ट आइटम्स का उपयोग करने के लिए पाइथन एरे को मजबूर कर सकता हूं?

+0

https://bugs.python.org/issue26821 –

+0

यह एक झूठी डिचोटोमी है: आपका प्रोग्राम दोनों कम स्मृति का उपयोग कर सकते हैं और तेज़ी से हो सकते हैं। हालांकि यह सवाल से असंबंधित है कि आप विभिन्न प्लेटफार्मों पर एक निश्चित आकार 'सरणी' आइटम का उपयोग कर सकते हैं ('सरणी 'शायद मंच के मूल निवासी सी प्रकार का उपयोग करता है)। यह एक अलग प्रश्न है: कैसे विशिष्ट numpy- आधारित गणना तेजी से बनाने के लिए। – jfs

उत्तर

5

आप रहना चाहते हैं array उपयोग करने के लिए, set the typecode

>>> array.array("I", range(10)).itemsize 
4 
: I ( unsigned int) के बजाय L ( unsigned long) करने के लिए

यह कहा गया है कि, अगर आप numx का उपयोग कर खो रहे हैं 2x से अधिक की गणना करने के लिए कोई रास्ता नहीं था, तो मैं बहुत हैरान होगा। यह जानने के बिना मुश्किल है कि आप उन मूल्यों के साथ क्या कर रहे हैं।

1

2 बातें: numpy.arange() (एक आंतरिक विधि)

का उपयोग करें और Numpy साथ बयानों के लिए उपयोग कर (कंप्यूटर की गति कारणों के लिए) से बचें। जितना संभव हो सके प्रसारण तकनीकों का उपयोग करने का प्रयास करें।

सभी वस्तुओं को प्राप्त करने का एक आसान तरीका है .ravel() अगर numpy सरणी का आकार रास्ते में हो रहा है।

python3 -m timeit -s "import numpy as np; a = np.arange(1000), 
....... dtype = np.uint32)" "for i in range(len(a)): a[i]" 

10000 छोरों, 3 का सबसे अच्छा: पाश प्रति 106 usec

python3 -m timeit -s "import numpy as np; a = np.arange(1000), 
....... dtype = np.uint32)" "a.ravel()" 

1000000 छोरों, 3 का सबसे अच्छा: पाश प्रति 0.218 usec

1

देखा गया here, array.array एक पुराना टूल है जिसमें कोई विशेष रुचि नहीं है (मेरे ज्ञान के लिए)।

आप दक्षता समस्या है तो numpy.arrayarray.array की तुलना में एक अच्छा विकल्प है, यह अनुकूलित vectorized उपकरणों का एक बहुत कुछ के साथ प्रदान की जाती है। इस मामले में, 32bits संचालन, अक्सर 64bits लोगों की तुलना में तेज हैं यहां तक ​​कि एक 64 बिट्स सिस्टम पर:

import numpy as np 
In [528]: %timeit np.sum(a32) 
1000 loops, best of 3: 1.86 ms per loop 

In [529]: %timeit np.sum(a64) 
100 loops, best of 3: 2.22 ms per loop 

In [530]: %timeit sum(a32) 
1 loop, best of 3: 572 ms per loop 

In [531]: %timeit sum(a64) 
1 loop, best of 3: 604 ms per loop 

जैसा कि आप देख, आप शुद्ध अजगर छोरों, जो धीमी है से बचना चाहिए।

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

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