Python에서 실제로 메모리를 운영 체제로 다시 릴리스하지 않기 때문에 Python 에서 메모리 사용량을 줄이는 것은 어렵습니다 . 객체를 삭제하면 새 Python 객체에서 메모리를 사용할 수 있지만 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).
데이터 프레임 크기 줄이기
가능하면 개체 dtype을 사용하지 마십시오.
>>> 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이있는 값은 박스형입니다. 즉, numpy 배열에는 포인터 만 포함되며 데이터 프레임의 모든 값에 대해 힙에 전체 Python 객체가 있습니다. 여기에는 문자열이 포함됩니다.
numpy는 배열에서 고정 크기 문자열을 지원하지만 pandas는 지원하지 않습니다 ( 사용자 혼란을 유발합니다 ). 이것은 상당한 차이를 만들 수 있습니다.
>>> 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
메모리 사용량보기
메모리 사용량을 볼 수 있습니다 ( docs ).
>>> 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
Pandas 0.17.1부터는 df.info(memory_usage='deep')
객체를 포함한 메모리 사용량을 볼 수도 있습니다.
gc
모듈을하고 전화를gc.collect()
하지만 메모리 복구 할 수 있습니다