एक पंडों के डेटाफ़्रेम को कितनी मेमोरी की आवश्यकता होगी इसका अनुमान कैसे लगाया जाए?


125

मैं सोच रहा था ... अगर मैं पढ़ रहा हूं, तो एक 400MB सीएसवी फ़ाइल को पंडों के डेटाफ़्रेम (read_csv या read_table का उपयोग करके) में दर्ज करें, क्या कोई तरीका है जिससे यह अनुमान लगाया जा सके कि इसकी कितनी मेमोरी की आवश्यकता होगी? बस डेटा फ्रेम और मेमोरी का एक बेहतर अनुभव प्राप्त करने की कोशिश कर रहा है ...


आप हमेशा इस प्रक्रिया को देख सकते हैं और यह एक फ़ाइल के लिए मेमोरी उपयोग है। यदि आप linux चला रहे हैं, topतो Shift + Mमेरी मेमोरी उपयोग को सॉर्ट करने के लिए प्रयास करें ।
JayQuerie.com

मुझे लगता है कि मुझे इस खुले पांडा मुद्दे का विज्ञापन करना चाहिए ।
एंडी हेडन

3
मेरे पास 4 मिलियन पंक्तियों के साथ एक बड़ी डेटाफ़्रेम है। मुझे पता चला कि इसके खाली उपसमूह को गणना करने के लिए सेकंड x=df.loc[[]]लगते हैं 0.1(शून्य पंक्तियों को निकालने के लिए) और, इसके अलावा, सैकड़ों मेगाबाइट मेमोरी लेता है, मूल डेटाफ़्रेम के रूप में, शायद कुछ नकल के कारण।
osa

पंडों के प्रमुख डेवलपर द्वारा पुरानी पोस्ट के लिए नया लिंक
सैलडी

जवाबों:


97

df.memory_usage() प्रत्येक कॉलम पर कितना कब्जा होता है:

>>> df.memory_usage()

Row_ID            20906600
Household_ID      20906600
Vehicle           20906600
Calendar_Year     20906600
Model_Year        20906600
...

इंडेक्स शामिल करने के लिए, पास करें index=True

तो समग्र स्मृति खपत प्राप्त करने के लिए:

>>> df.memory_usage(index=True).sum()
731731000

इसके अलावा, पासिंग deep=Trueएक अधिक सटीक मेमोरी उपयोग रिपोर्ट को सक्षम करेगा, जिसमें निहित वस्तुओं के पूर्ण उपयोग के लिए खाते हैं।

ऐसा इसलिए है क्योंकि मेमोरी के उपयोग में ऐसे तत्वों द्वारा खपत की गई मेमोरी शामिल नहीं है जो deep=False(डिफ़ॉल्ट केस) यदि ऐरे के घटक नहीं हैं ।


1
सभी स्तंभों की मेमोरी का योग वास्तव में मेमोरी उपयोग पर प्रभाव है? मैं कल्पना कर सकता हूं कि अधिक उपरि होना चाहिए।
अग्निशमन

14
आप वास्तव में भी चाहते हैंdeep=True
smci

Df.memory_usage () का योग sys.getsizeof (df) के बराबर नहीं है! कई ओवरहेड्स हैं। जैसा कि स्मिकी ने उल्लेख किया है, आपको जरूरत हैdeep=True
योनि

11
FYI करें, memory_usage()बाइट्स में मेमोरी का उपयोग करता है (जैसा कि आप उम्मीद करेंगे)।
13

2
क्यों के साथ / बिना गहरे = सच के इतना बड़ा अंतर?
नगुई अल

83

यहां विभिन्न तरीकों की तुलना की जाती है - sys.getsizeof(df)सबसे सरल है।

इस उदाहरण के लिए, df814 पंक्तियों, 11 कॉलमों (2 ints, 9 ऑब्जेक्ट्स) के साथ एक डेटाफ्रेम है - एक 427kb आकृति से पढ़ा जाता है

sys.getsizeof (DF)

>>> आयात sys
>>> sys.getsizeof (df)
(बाइट्स में परिणाम देता है)
462,456

df.memory_usage ()

>>> df.memory_usage ()
...
(प्रत्येक कॉलम को 8 बाइट्स / पंक्ति में सूचीबद्ध करता है)

>>> df.memory_usage ()। योग ()
71,712
(लगभग पंक्तियाँ * बछड़े * 8 बाइट्स)

>>> df.memory_usage (गहरा = सत्य)
(प्रत्येक कॉलम के पूर्ण मेमोरी उपयोग को सूचीबद्ध करता है)

>>> df.memory_usage (गहरा = सत्य) .sum ()
(बाइट्स में परिणाम देता है)
462,432

df.info ()

प्रिंट करने के लिए डेटाफ़्रेम जानकारी प्रिंट करता है। तकनीकी रूप से ये किबिबाइट्स (KiB) हैं, किलोबाइट नहीं - जैसा कि डॉकस्ट्रिंग कहते हैं, "मेमोरी उपयोग मानव-पठनीय इकाइयों (बेस -2 प्रतिनिधित्व) में दिखाया गया है।" इसलिए बाइट पाने के लिए 1024 से गुणा करना होगा, जैसे 451.6 KiB = 462,438 बाइट।

>>> df.info ()
...
मेमोरी उपयोग: 70.0+ KB

>>> df.info (memory_usage = 'deep')
...
मेमोरी उपयोग: 451.6 KB

g उपरोक्त कोड क्या ऑब्जेक्ट या मॉड्यूल को संदर्भित करता है?
zozo

@ ज़ोज़ो वूप्स - एक टाइपो था - फिक्स्ड
ब्रायन बर्न्स

2
मैं का उपयोग करें df.info(memory_usage="deep"), यह रिटर्न "392.6 एमबी", जबकि sys.getsizeof(df)और df.memory_usage(index=True, deep=True).sum()दोनों वापसी लगभग "411,718,016" (~ 411MB)। क्या आप बता सकते हैं कि 3 परिणाम सुसंगत क्यों नहीं हैं? धन्यवाद
Catbuilts

2
@BrianBurns: के df.memory_usage(deep=True).sum()साथ लगभग एक ही रिटर्न df.memory_usage(index=True, deep=True).sum()। मेरे मामले में, indexबहुत याद नहीं है। दिलचस्प रूप से पर्याप्त है, मैंने पाया कि 411718016/1024/1024 = 392.6, बाइट को एमबी में बदलने के लिए df.info(memory_usage="deep")उपयोग 2^10कर सकता है , जो मुझे भ्रमित करता है। वैसे भी आपकी मदद के लिए धन्यवाद: डी।
प्रात:

1
@ कैटिफ़्टर्स आह, जो इसे समझाते हैं! df.infomebibytes (2 ^ 10) लौटा रहा है, मेगाबाइट नहीं (10 ^ 6) - उत्तर में संशोधन करेगा।
ब्रायन बर्न्स

43

मुझे लगा कि मैं चर्चा में कुछ और आंकड़े लाऊंगा।

मैंने इस मुद्दे पर कई परीक्षण किए।

अजगर resourceपैकेज का उपयोग करके मुझे अपनी प्रक्रिया का मेमोरी उपयोग मिला।

और csv को StringIOबफर में लिखकर , मैं बाइट्स में इसका आकार आसानी से माप सकता हूं।

मैंने दो प्रयोग किए, प्रत्येक ने 10,000 लाइनों और 1,000,000 लाइनों के बीच बढ़ते आकारों के 20 डेटाफ्रेम बनाए। दोनों में 10 कॉलम हैं।

पहले प्रयोग में मैंने अपने डेटासेट में केवल फ्लोट्स का उपयोग किया था।

यह है कि लाइनों की संख्या के एक समारोह के रूप में सीएसवी फ़ाइल की तुलना में मेमोरी कैसे बढ़ी। (मेगाबाइट में आकार)

मेमोरी और सीएसवी आकार मेगाबाइट में फ्लोट प्रविष्टियों के साथ पंक्तियों की संख्या के एक समारोह के रूप में

दूसरा प्रयोग मेरे पास एक ही दृष्टिकोण था, लेकिन डेटासेट में डेटा केवल छोटे तारों से बना था।

मेमोरी और सीएसवी का आकार मेगाबाइट में स्ट्रिंग प्रविष्टियों के साथ पंक्तियों की संख्या के एक समारोह के रूप में

ऐसा लगता है कि सीएसवी के आकार और डेटाफ़्रेम के आकार का संबंध काफी भिन्न हो सकता है, लेकिन मेमोरी का आकार हमेशा 2-3 के कारक (इस प्रयोग में फ्रेम आकार के लिए) से बड़ा होगा

मैं इस उत्तर को और प्रयोगों के साथ पूरा करना पसंद करूंगा, कृपया मुझे टिप्पणी करें यदि आप चाहते हैं कि मैं कुछ विशेष कोशिश करूं।


आपका y अक्ष क्या है?
इल्या वी। शूरोव

1
मेगाबाइट्स में डिस्क पर max_rss और csv का आकार
फ़ायरलाइनx

31

आपको इसे उल्टा करना होगा।

In [4]: DataFrame(randn(1000000,20)).to_csv('test.csv')

In [5]: !ls -ltr test.csv
-rw-rw-r-- 1 users 399508276 Aug  6 16:55 test.csv

तकनीकी रूप से मेमोरी इस बारे में है (जिसमें इंडेक्स शामिल हैं)

In [16]: df.values.nbytes + df.index.nbytes + df.columns.nbytes
Out[16]: 168000160

तो 400MB फ़ाइल के साथ मेमोरी में 168MB, 20 फ्लोट कॉलम की 1M पंक्तियाँ

DataFrame(randn(1000000,20)).to_hdf('test.h5','df')

!ls -ltr test.h5
-rw-rw-r-- 1 users 168073944 Aug  6 16:57 test.h5

MUCH अधिक कॉम्पैक्ट जब एक बाइनरी HDF5 फ़ाइल के रूप में लिखा जाता है

In [12]: DataFrame(randn(1000000,20)).to_hdf('test.h5','df',complevel=9,complib='blosc')

In [13]: !ls -ltr test.h5
-rw-rw-r-- 1 users 154727012 Aug  6 16:58 test.h5

डेटा यादृच्छिक था, इसलिए संपीड़न बहुत अधिक मदद नहीं करता है


यह बहुत चालाक है! किसी भी विचार का उपयोग करके फ़ाइल को पढ़ने के लिए आवश्यक मेमोरी को कैसे मापें read_csv?
एंडी हेडन

कोई विचार नहीं है कि आप कैसे पढ़ते हैं; IIRC यह डेटा को पकड़ने के लिए आवश्यक अंतिम मेमोरी को 2x तक बढ़ा सकता है (wes के लेख से), लेकिन मुझे लगता है कि वह इसे लगातार + अंतिम मेमोरी में लाया
जेफ

आह, मुझे फिर से पढ़ने की ज़रूरत है, मुझे याद आया कि 2x एक निश्चित एल्गोरिथ्म के लिए कुछ सुविधाजनक सैद्धांतिक मंत्री है, अगर यह कम है जो कोयल है।
एंडी हेडन

आप (वास्तविक समय में) IO के प्रदर्शन की iotopतरह top/ उपयोग कर सकते हैं htop
फिलिप क्लाउड

1
nbytesयदि आपके पास एक डेटाफ्रेम में तार हैं, तो एक सकल कम हो जाएगा।
osa

10

यदि आपको dtypeअपने सरणी की जानकारी है तो आप सीधे बाइट की संख्या की गणना कर सकते हैं जो कि आपके डेटा + को पायथन ऑब्जेक्ट्स के लिए स्वयं संग्रहीत करने में ले जाएगा। numpyसरणियों का एक उपयोगी गुण है nbytes। आप एक पंडों में सरणियों से बाइट्स की संख्या प्राप्त कर सकते DataFrameहैं

nbytes = sum(block.values.nbytes for block in df.blocks.values())

objectdtype सरणियाँ प्रति ऑब्जेक्ट 8 बाइट्स संग्रहीत करती हैं (ऑब्जेक्ट dtype सरणियाँ एक अपारदर्शी के लिए एक पॉइंटर स्टोर करती हैं PyObject), इसलिए यदि आपके सीएसवी में तार हैं, तो आपको इस बात का ध्यान रखना read_csvहोगा कि जो objectdtype सरणियों में बदल जाएंगे और तदनुसार अपनी गणना समायोजित करेंगे।

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

अधिक विवरण के लिए numpyअदिश प्रकार पृष्ठ देखें object dtype। चूंकि केवल एक संदर्भ संग्रहीत किया जाता है, इसलिए आपको सरणी में ऑब्जेक्ट के आकार को भी ध्यान में रखना होगा। जैसा कि वह पृष्ठ कहता है, ऑब्जेक्ट सरणियां कुछ हद तक पायथन listवस्तुओं के समान हैं।


धन्यवाद फिलिप! बस स्पष्ट करने के लिए - एक स्ट्रिंग के लिए हमें एक स्ट्रिंग ऑब्जेक्ट के लिए पॉइंटर के लिए 8 बाइट्स की आवश्यकता होगी, साथ ही वास्तविक स्ट्रिंग ऑब्जेक्ट?
ऐनी

1
हां, किसी भी ऑब्जेक्ट प्रकार के लिए आपको 8 बाइट पॉइंटर + साइज (ऑब्जेक्ट) की आवश्यकता होगी
विक्टर केर्केज़

1
सुझाव df.blocks.values ​​() ऐसा लग रहा है कि df.blocks अब एक तानाशाही है
MRocklin

8

हाँ वहाँ है। पंडों ने अपने डेटा को dtypes ndarrayद्वारा समूहीकृत करने वाली 2 आयामी सुव्यवस्थित संरचनाओं में संग्रहीत किया जाएगा। ndarrayमूल रूप से एक छोटे हेडर के साथ डेटा का एक कच्चा सी सरणी है। तो आप अनुमान लगा सकते हैं कि इसका आकार सिर्फ उस आकार को गुणा करके dtypeहै जिसमें सरणी के आयाम शामिल हैं।

उदाहरण के लिए: यदि आपके पास 2 np.int32और 5 np.float64कॉलम वाली 1000 पंक्तियाँ हैं, तो आपके DataFrame में एक 2x1000 np.int32सरणी और एक 5x1000 np.float64सरणी है:

4bytes * 2 * 1000 + 8bytes * 5 * 1000 = 48000 बाइट्स


@AndyHayden आप निर्माण लागत का क्या मतलब है? के उदाहरण का आकार DataFrame?
फिलिप बादल

धन्यवाद विक्टर! @ और - कोई भी विचार निर्माण लागत कितनी बड़ी है?
ऐनी

यह शामिल नहीं है, लेकिन साइथन में pandasएक बहुत ही कुशल कार्यान्वयन read_tableहै (यह स्तूप के लोडटेक्स्ट की तुलना में बहुत बेहतर है) इसलिए मैं मानता हूं कि यह डेटा को सीधे पार्स करता है और संग्रहीत करता है ndarray
विक्टर केर्केज़

@PhillipCloud आपको इसका निर्माण करना है, जो स्मृति लेता है .. मुझे लगता है कि दो बार आकार का उल्लेख याद है? ...
एंडी हेडन

6

मेरा मानना ​​है कि यह इन-मेमोरी साइज़ को किसी भी चीज़ को अजगर में शामिल करता है। पंडों और सुन्न के संबंध में इंटर्न को जांचने की आवश्यकता है

>>> import sys
#assuming the dataframe to be df 
>>> sys.getsizeof(df) 
59542497
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.