नियमित पायथन सूचियों पर NumPy के क्या फायदे हैं?


466

नियमित पायथन सूचियों पर NumPy के क्या फायदे हैं ?

मेरे पास लगभग 100 वित्तीय बाजार श्रृंखलाएं हैं, और मैं 100x100x100 = 1 मिलियन कोशिकाओं का घन सरणी बनाने जा रहा हूं। मैं मानक त्रुटियों के साथ सरणी को भरने के लिए प्रत्येक y और z के साथ प्रत्येक x (3-चर) को पुनः प्राप्त करूंगा।

मैंने सुना है कि "बड़े मैट्रिसेस" के लिए मुझे प्रदर्शन और स्केलेबिलिटी कारणों से पायथन सूचियों के विपरीत न्यूमपी का उपयोग करना चाहिए। बात यह है, मुझे पता है कि पायथन सूचियां हैं और वे मेरे लिए काम करते हैं।

अगर मैं न्यूमपी में जाता हूं तो क्या लाभ होंगे?

क्या होगा अगर मेरे पास 1000 सीरीज़ (यानी, क्यूब में 1 बिलियन फ्लोटिंग पॉइंट सेल) हैं?

जवाबों:


727

NumPy के सरणियाँ Python सूचियों की तुलना में अधिक कॉम्पैक्ट हैं - जैसा कि आप वर्णन करते हैं, Python में सूचियों की एक सूची, कम से कम 20 MB या तो लेगी, जबकि कक्षों में एकल-सटीक फ़्लोट्स वाला एक NumPy 3D सरणी 4 MB में फिट होगी। NumPy के साथ पढ़ने और लिखने की वस्तुओं तक पहुंच भी तेज़ है।

हो सकता है कि आप केवल एक लाख कोशिकाओं की परवाह न करें, लेकिन आप निश्चित रूप से एक अरब कोशिकाओं के लिए होंगे - न तो दृष्टिकोण 32-बिट आर्किटेक्चर में फिट होगा, बल्कि 64-बिट बिल्ड के साथ NumPy 4 जीबी या तो के साथ दूर हो जाएगा , अकेले पायथन को कम से कम 12 जीबी (बहुत सारे पॉइंटर्स जो कि आकार में दोगुना है) की आवश्यकता होगी - हार्डवेयर का एक बहुत महंगा टुकड़ा!

अंतर ज्यादातर "अप्रत्यक्षता" के कारण होता है - पायथन सूची पायथन ऑब्जेक्ट्स की ओर इशारा करती है, कम से कम 4 बाइट्स प्रति पॉइंटर प्लस 16 बाइट्स के लिए यहां तक ​​कि सबसे छोटी पायथन ऑब्जेक्ट (टाइप पॉइंटर के लिए 4, संदर्भ गणना के लिए 4, 4 मूल्य के लिए - और मेमोरी आवंटन 16 तक राउंड)। एक NumPy सरणी समान मानों का एक सरणी है - एकल-सटीक संख्या में 4 बाइट्स प्रत्येक, डबल-सटीक वाले, 8 बाइट्स होते हैं। कम लचीला, लेकिन आप मानक पायथन सूचियों के लचीलेपन के लिए पर्याप्त रूप से भुगतान करते हैं!


मैं "Sys.getsizeof ()" का उपयोग करने की कोशिश कर रहा हूं ताकि समान तत्वों के साथ पायथन सूचियों और NumPy सरणियों के आकार की तुलना की जा सके और यह इंगित नहीं होता है कि NumPy सरणियां बहुत छोटी थीं। क्या यह मामला है या sys.getizeof () में यह पता लगाने की समस्या है कि कितना बड़ा Numyy सरणी है?
जैक सिम्पसन

3
@JackSimpson getsizeofविश्वसनीय नहीं है। दस्तावेज़ीकरण में स्पष्ट रूप से कहा गया है कि: केवल ऑब्जेक्ट के लिए सीधे जिम्मेदार मेमोरी खपत का हिसाब है, न कि उन वस्तुओं की मेमोरी खपत जो इसे संदर्भित करता है। इसका मतलब है कि यदि आपके पास नेस्टेड अजगर सूचीबद्ध है तो तत्वों के आकार को ध्यान में नहीं रखा जाता है।
बाकूरी

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

@AlexMartelli, क्या आप मुझे बता सकते हैं कि ये नंबर आपको कहां मिल रहे हैं?
lmiguelvargasf

बस एक हेड अप, सूचियों की सूची के बराबर पायथन सूची के आकार पर आपका अनुमान बंद है। सी floatएस (4 बाइट्स) का 4 जीबी का नुकीला सरणी 32 जीबी मूल्य के listएस और पायथन floatएस (जो वास्तव में सी doubleएस) के करीब है , 12 जीबी के लिए अनुवाद नहीं करेगा; float64 बिट पायथन पर प्रत्येक ~ 24 बाइट्स (एलोकेटर में कोई संरेखण नुकसान नहीं मानते) पर कब्जा कर लेता है, साथ listही संदर्भ को रखने के लिए एक और 8 बाइट्स (और जो कि listस्वयं के लिए समग्र और ऑब्जेक्ट हेडर को अनदेखा करता है , जो एक जीबी के आधार पर हो सकता है) वास्तव में कुल मिलाकर कितना होता है)।
शैडो रेंजर

232

NumPy सिर्फ अधिक कुशल नहीं है; यह अधिक सुविधाजनक भी है। आपको बहुत सारे वेक्टर और मैट्रिक्स ऑपरेशन मुफ्त में मिलते हैं, जो कभी-कभी किसी को अनावश्यक काम से बचने की अनुमति देते हैं। और उन्हें कुशलता से लागू भी किया जाता है।

उदाहरण के लिए, आप अपने क्यूब को एक फ़ाइल से सीधे एक सरणी में पढ़ सकते हैं:

x = numpy.fromfile(file=open("data"), dtype=float).reshape((100, 100, 100))

दूसरे आयाम के साथ योग:

s = x.sum(axis=1)

पता करें कि कौन सी कोशिकाएं एक सीमा से ऊपर हैं:

(x > 0.5).nonzero()

तीसरे आयाम के साथ हर समान-अनुक्रमित स्लाइस को निकालें:

x[:, :, ::2]

इसके अलावा, कई उपयोगी पुस्तकालय NumPy सरणियों के साथ काम करते हैं। उदाहरण के लिए, सांख्यिकीय विश्लेषण और विज़ुअलाइज़ेशन लाइब्रेरी।

यहां तक ​​कि अगर आपको प्रदर्शन की समस्या नहीं है, तो भी NumPy सीखने का प्रयास करने लायक है।


धन्यवाद - आपने अपने तीसरे उदाहरण में एक और अच्छा कारण प्रदान किया है, वास्तव में, मैं दहलीज से ऊपर की कोशिकाओं के लिए मैट्रिक्स की खोज करूंगा। इसके अलावा, मैं sqlLite से लोड हो रहा था। फ़ाइल दृष्टिकोण बहुत अधिक कुशल होगा।
थॉमस ब्राउन

112

एलेक्स ने मेमोरी दक्षता और रॉबर्टो की सुविधा का उल्लेख किया है, और ये दोनों अच्छे बिंदु हैं। कुछ और विचारों के लिए, मैं गति और कार्यक्षमता का उल्लेख करूँगा ।

कार्यशीलता: आपको न्यूमपी, एफएफटी, दीक्षांत, तेजी से खोज, बुनियादी आँकड़े, रैखिक बीजगणित, हिस्टोग्राम, आदि के साथ बहुत कुछ मिलता है और वास्तव में, एफएफटी के बिना कौन रह सकता है?

गति: यहां एक सूची और एक NumPy सरणी पर एक योग करने पर एक परीक्षण है, यह दर्शाता है कि NumPy सरणी पर योग 10x तेज है (इस परीक्षण में - लाभ भिन्न हो सकता है)।

from numpy import arange
from timeit import Timer

Nelements = 10000
Ntimeits = 10000

x = arange(Nelements)
y = range(Nelements)

t_numpy = Timer("x.sum()", "from __main__ import x")
t_list = Timer("sum(y)", "from __main__ import y")
print("numpy: %.3e" % (t_numpy.timeit(Ntimeits)/Ntimeits,))
print("list:  %.3e" % (t_list.timeit(Ntimeits)/Ntimeits,))

जो मेरे सिस्टम पर (जबकि मैं बैकअप चला रहा हूं) देता है:

numpy: 3.004e-05
list:  5.363e-04

44

यहाँ scipy.org वेबसाइट पर FAQ से अच्छा जवाब दिया गया है :

पायथॉन सूचियों पर नम्पी सरणियाँ क्या लाभ प्रदान करती हैं?

अजगर की सूचियाँ कुशल सामान्य प्रयोजन कंटेनर हैं। वे (काफी) कुशल सम्मिलन, विलोपन, एपेंडिंग और कॉन्सेटेशन का समर्थन करते हैं, और पायथन की सूची समझ उन्हें निर्माण और हेरफेर करने में आसान बनाती है। हालाँकि, उनकी कुछ सीमाएँ हैं: वे तत्व-परिवर्धन और गुणन जैसे "वेक्टराइज्ड" ऑपरेशनों का समर्थन नहीं करते हैं, और यह तथ्य कि उनमें विभिन्न प्रकार की वस्तुएं हो सकती हैं, जिसका अर्थ है कि पायथन को प्रत्येक तत्व के लिए टाइप जानकारी संग्रहीत करनी चाहिए, और प्रकार प्रेषण कोड निष्पादित करना होगा प्रत्येक तत्व पर कार्य करते समय। इसका मतलब यह भी है कि बहुत कम सूची संचालन कुशल सी छोरों द्वारा किया जा सकता है - प्रत्येक पुनरावृत्ति को टाइप चेक और अन्य पायथन एपीआई बुककीपिंग की आवश्यकता होगी।


9

सभी ने सुन्न सरणी और अजगर सूची के बीच लगभग सभी प्रमुख अंतरों पर प्रकाश डाला है, मैं उन्हें केवल यहां बताऊंगा:

  1. पाइथन लिस्ट (जो गतिशील रूप से बढ़ सकती है) के विपरीत, Numpy सरणियों का निर्माण में एक निश्चित आकार होता है। Ndarray के आकार को बदलने से एक नया सरणी बन जाएगा और मूल को हटा दिया जाएगा।

  2. एक Numpy सरणी में तत्व सभी एक ही डेटा प्रकार के होने के लिए आवश्यक हैं (हम विषम प्रकार के भी हो सकते हैं लेकिन यह आपको गणितीय कार्यों की अनुमति नहीं देगा) और इस प्रकार मेमोरी में एक ही आकार होगा

  3. Numpy सरणियों को बड़ी संख्या में डेटा पर गणितीय और अन्य प्रकार के संचालन की सुविधा दी जाती है। आमतौर पर इस तरह के संचालन को अधिक कुशलता से क्रियान्वित किया जाता है और अनुक्रमों में अजगर के निर्माण से कम कोड का उपयोग संभव है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.