Python'da bellek kullanımını azaltmak zordur çünkü Python, belleği işletim sistemine geri vermez . Nesneleri silerseniz, bellek yeni Python nesneleri tarafından kullanılabilir, ancak free()
sisteme geri dönmez ( bu soruya bakın ).
Sayısal sayısal dizilere sadık kalırsanız, bunlar serbest bırakılır, ancak kutulu nesneler serbest bırakılmaz.
>>> 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
Dataframe Sayısını Azaltma
Python belleğimizi yüksek filigranda tutar, ancak oluşturduğumuz toplam veri çerçevesi sayısını azaltabiliriz. Veri çerçevenizi değiştirirken, inplace=True
kopya oluşturmamak için tercih edin .
Diğer bir yaygın sorun, ipython'da önceden oluşturulmuş veri çerçevelerinin kopyalarını tutmaktır:
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
Geçmişinizi temizlemek için yazarak bunu düzeltebilirsiniz . Alternatif olarak, ipython'un ne kadar geçmişle kalacağını ayarlayabilirsiniz ipython --cache-size=5
(varsayılan 1000'dir).
Dataframe Boyutunu Azaltma
Mümkün olan her yerde nesne tiplerini kullanmaktan kaçının.
>>> df.dtypes
foo float64 # 8 bytes per value
bar int64 # 8 bytes per value
baz object # at least 48 bytes per value, often more
Nesne dtype içeren değerler kutu içine alınmıştır, bu da numpy dizisinin yalnızca bir işaretçi içerdiği ve veri çerçevenizdeki her değer için yığın üzerinde tam bir Python nesnesine sahip olduğunuz anlamına gelir. Bu dizeleri içerir.
Numpy dizilerde sabit boyutlu dizeleri desteklerken, pandalar desteklemez ( kullanıcının kafasının karışmasına neden olur ). Bu, önemli bir fark yaratabilir:
>>> 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
Dize sütunlarını kullanmaktan kaçınmak veya dize verilerini sayı olarak temsil etmenin bir yolunu bulmak isteyebilirsiniz.
Birçok tekrarlanan değer içeren bir veri çerçeveniz varsa (NaN çok yaygındır), bellek kullanımını azaltmak için seyrek bir veri yapısı kullanabilirsiniz:
>>> 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
Bellek Kullanımını Görüntüleme
Bellek kullanımını görüntüleyebilirsiniz ( belgeler ):
>>> 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
Pandalar 0.17.1'den itibaren, df.info(memory_usage='deep')
nesneler dahil bellek kullanımını görmek için de yapabilirsiniz .
gc
modülü içe aktarabilir ve çağırabilirsiniz,gc.collect()
ancak belleği kurtaramayabilir