पायथन में मेमोरी का उपयोग कम करना मुश्किल है, क्योंकि पायथन वास्तव में मेमोरी को ऑपरेटिंग सिस्टम में वापस नहीं करता है । यदि आप ऑब्जेक्ट्स को हटाते हैं, तो मेमोरी नए पायथन ऑब्जेक्ट्स के लिए उपलब्ध है, लेकिन free()
सिस्टम में वापस नहीं आई ( यह प्रश्न देखें )।
यदि आप संख्यात्मक सुन्न सरणियों से चिपके रहते हैं, तो उन्हें मुक्त कर दिया जाता है, लेकिन बॉक्सिंग ऑब्जेक्ट नहीं हैं।
>>> import os, psutil, numpy as np
>>> def usage():
... process = psutil.Process(os.getpid())
... return process.get_memory_info()[0] / float(2 ** 20)
...
>>> usage() # initial memory usage
27.5
>>> arr = np.arange(10 ** 8) # create a large array without boxing
>>> usage()
790.46875
>>> del arr
>>> usage()
27.52734375 # numpy just free()'d the array
>>> arr = np.arange(10 ** 8, dtype='O') # create lots of objects
>>> usage()
3135.109375
>>> del arr
>>> usage()
2372.16796875 # numpy frees the array, but python keeps the heap big
डेटाफ्रेम की संख्या को कम करना
अजगर हमारी स्मृति को उच्च वॉटरमार्क पर रखता है, लेकिन हम हमारे द्वारा बनाए गए डेटाफ्रेम की कुल संख्या को कम कर सकते हैं। अपने डेटाफ़्रेम को संशोधित करते समय, पसंद करें inplace=True
, ताकि आप प्रतियां न बनाएँ।
एक और आम गोथा, जो पहले से तैयार डेटाफ़्रेम की प्रतियों को ipython में पकड़े हुए है:
In [1]: import pandas as pd
In [2]: df = pd.DataFrame({'foo': [1,2,3,4]})
In [3]: df + 1
Out[3]:
foo
0 2
1 3
2 4
3 5
In [4]: df + 2
Out[4]:
foo
0 3
1 4
2 5
3 6
In [5]: Out # Still has all our temporary DataFrame objects!
Out[5]:
{3: foo
0 2
1 3
2 4
3 5, 4: foo
0 3
1 4
2 5
3 6}
आप %reset Out
अपना इतिहास साफ़ करने के लिए इसे टाइप करके ठीक कर सकते हैं । वैकल्पिक रूप से, आप समायोजित कर सकते हैं कि ipython कितना इतिहास रखता है ipython --cache-size=5
(डिफ़ॉल्ट 1000 है)।
डेटाफ़्रेम आकार को कम करना
जहां भी संभव हो, वस्तु dtypes का उपयोग करने से बचें।
>>> df.dtypes
foo float64 # 8 bytes per value
bar int64 # 8 bytes per value
baz object # at least 48 bytes per value, often more
किसी ऑब्जेक्ट dtype वाले मानों को बॉक्स किया जाता है, जिसका अर्थ है कि केवल एक सरणी में सूचक समाहित होता है और आपके डेटाफ़्रेम में प्रत्येक मान के लिए ढेर पर एक पूर्ण पायथन ऑब्जेक्ट होता है। इसमें तार शामिल हैं।
Whilst numpy सरणियों में निश्चित आकार के तार का समर्थन करता है, पांडा नहीं करता है ( यह उपयोगकर्ता भ्रम का कारण है )। यह एक महत्वपूर्ण अंतर बना सकता है:
>>> import numpy as np
>>> arr = np.array(['foo', 'bar', 'baz'])
>>> arr.dtype
dtype('S3')
>>> arr.nbytes
9
>>> import sys; import pandas as pd
>>> s = pd.Series(['foo', 'bar', 'baz'])
dtype('O')
>>> sum(sys.getsizeof(x) for x in s)
120
आप स्ट्रिंग कॉलम का उपयोग करने से बचना चाहते हैं, या संख्याओं के रूप में स्ट्रिंग डेटा का प्रतिनिधित्व करने का एक तरीका खोज सकते हैं।
यदि आपके पास एक डेटाफ्रेम है जिसमें कई दोहराया मान हैं (NaN बहुत आम है), तो आप मेमोरी उपयोग को कम करने के लिए एक विरल डेटा संरचना का उपयोग कर सकते हैं :
>>> df1.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 39681584 entries, 0 to 39681583
Data columns (total 1 columns):
foo float64
dtypes: float64(1)
memory usage: 605.5 MB
>>> df1.shape
(39681584, 1)
>>> df1.foo.isnull().sum() * 100. / len(df1)
20.628483479893344 # so 20% of values are NaN
>>> df1.to_sparse().info()
<class 'pandas.sparse.frame.SparseDataFrame'>
Int64Index: 39681584 entries, 0 to 39681583
Data columns (total 1 columns):
foo float64
dtypes: float64(1)
memory usage: 543.0 MB
मेमोरी उपयोग देखना
आप मेमोरी उपयोग ( डॉक्स ) देख सकते हैं :
>>> df.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 39681584 entries, 0 to 39681583
Data columns (total 14 columns):
...
dtypes: datetime64[ns](1), float64(8), int64(1), object(4)
memory usage: 4.4+ GB
पांडा 0.17.1 के अनुसार, आप df.info(memory_usage='deep')
ऑब्जेक्ट सहित मेमोरी उपयोग को देखने के लिए भी कर सकते हैं।
gc
मॉड्यूल और कॉल को भी आयात कर सकते हैंgc.collect()
लेकिन यह मेमोरी को पुनर्प्राप्त नहीं कर सकता है