Mengurangi penggunaan memori dengan Python itu sulit, karena Python tidak benar-benar melepaskan memori ke sistem operasi . Jika Anda menghapus objek, maka memori tersedia untuk objek Python baru, tetapi tidak free()
kembali ke sistem ( lihat pertanyaan ini ).
Jika Anda tetap berpegang pada larik numpy numerik, itu dibebaskan, tetapi objek kotak tidak.
>>> 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
Mengurangi Jumlah Kerangka Data
Python menjaga memori kita pada watermark tinggi, tapi kita bisa mengurangi jumlah total dataframe yang kita buat. Saat memodifikasi kerangka data Anda, lebih baik inplace=True
, jadi Anda tidak membuat salinan.
Gotcha umum lainnya memegang salinan dari dataframe yang dibuat sebelumnya di 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}
Anda dapat memperbaikinya dengan mengetik %reset Out
untuk menghapus riwayat Anda. Atau, Anda dapat menyesuaikan berapa banyak histori yang disimpan ipython ipython --cache-size=5
(defaultnya adalah 1000).
Mengurangi Ukuran Dataframe
Jika memungkinkan, hindari menggunakan dtypes objek.
>>> df.dtypes
foo float64 # 8 bytes per value
bar int64 # 8 bytes per value
baz object # at least 48 bytes per value, often more
Nilai dengan objek dtype diberi kotak, yang berarti array numpy hanya berisi pointer dan Anda memiliki objek Python penuh di heap untuk setiap nilai dalam dataframe Anda. Ini termasuk string.
Sementara numpy mendukung string berukuran tetap dalam array, panda tidak ( ini menyebabkan kebingungan pengguna ). Ini dapat membuat perbedaan yang signifikan:
>>> 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
Anda mungkin ingin menghindari penggunaan kolom string, atau mencari cara untuk merepresentasikan data string sebagai angka.
Jika Anda memiliki kerangka data yang berisi banyak nilai berulang (NaN sangat umum), Anda dapat menggunakan struktur data renggang untuk mengurangi penggunaan memori:
>>> 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
Melihat Penggunaan Memori
Anda dapat melihat penggunaan memori ( dokumen ):
>>> 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
Pada pandas 0.17.1, Anda juga dapat melakukannya df.info(memory_usage='deep')
untuk melihat penggunaan memori termasuk objek.
gc
modul dan memanggilgc.collect()
tetapi mungkin tidak memulihkan memori