복붙노트

[PYTHON] 팬더 : 여기서 메모리 누수가 어디 있지?

PYTHON

팬더 : 여기서 메모리 누수가 어디 있지?

Python에서 pandas 라이브러리를 사용하여 메모리 누수 문제를 직면합니다. 내 클래스에서 pandas.dataframe 개체를 만들고 내 조건에 따라 데이터 프레임 크기를 변경하는 메서드가 있습니다. 데이터 프레임 크기를 변경하고 새로운 팬더 객체를 생성 한 후에 클래스에서 원본 pandas.dataframe을 다시 작성합니다. 그러나 초기 테이블을 크게 줄인 후에도 메모리 사용량은 매우 높습니다. 간단한 예제 코드 (프로세스 관리자를 작성하지 않았습니다. 작업 관리자 참조) :

import time, string, pandas, numpy, gc
class temp_class ():

    def __init__(self, nrow = 1000000, ncol = 4, timetest = 5):

        self.nrow = nrow
        self.ncol = ncol
        self.timetest = timetest

    def createDataFrame(self):

        print('Check memory before dataframe creating')
        time.sleep(self.timetest)
        self.df = pandas.DataFrame(numpy.random.randn(self.nrow, self.ncol),
            index = numpy.random.randn(self.nrow), columns = list(string.letters[0:self.ncol]))
        print('Check memory after dataFrame creating')
        time.sleep(self.timetest)

    def changeSize(self, from_ = 0, to_ = 100):

        df_new = self.df[from_:to_].copy()
        print('Check memory after changing size')
        time.sleep(self.timetest)

        print('Check memory after deleting initial pandas object')
        del self.df
        time.sleep(self.timetest)

        print('Check memory after deleting copy of reduced pandas object')
        del df_new
        gc.collect()
        time.sleep(self.timetest)

if __name__== '__main__':

    a = temp_class()
    a.createDataFrame()
    a.changeSize()

16 메가 바이트?

Windows 7 (x64) 시스템에서 Python 2.7.2 (x32)를 사용합니다. pandas.version은 0.7.3입니다. numpy.version은 1.6.1입니다.

해결법

  1. ==============================

    1.몇 가지 지적해야 할 점은 다음과 같습니다.

    몇 가지 지적해야 할 점은 다음과 같습니다.

    나는 이것을 들여다 보았고 판다가 기억을 새기지 않는다는 것을 확신 할 수 있습니다. memory_profiler (http://pypi.python.org/pypi/memory_profiler) 패키지를 사용하고 있습니다.

    import time, string, pandas, numpy, gc
    from memory_profiler import LineProfiler, show_results
    import memory_profiler as mprof
    
    prof = LineProfiler()
    
    @prof
    def test(nrow=1000000, ncol = 4, timetest = 5):
        from_ = nrow // 10
        to_ = 9 * nrow // 10
        df = pandas.DataFrame(numpy.random.randn(nrow, ncol),
                              index = numpy.random.randn(nrow),
                              columns = list(string.letters[0:ncol]))
        df_new = df[from_:to_].copy()
        del df
        del df_new
        gc.collect()
    
    test()
    # for _ in xrange(10):
    #     print mprof.memory_usage()
    
    show_results(prof)
    

    그리고 여기 출력

    10:15 ~/tmp $ python profmem.py 
    Line #    Mem usage  Increment   Line Contents
    ==============================================
         7                           @prof
         8     28.77 MB    0.00 MB   def test(nrow=1000000, ncol = 4, timetest = 5):
         9     28.77 MB    0.00 MB       from_ = nrow // 10
        10     28.77 MB    0.00 MB       to_ = 9 * nrow // 10
        11     59.19 MB   30.42 MB       df = pandas.DataFrame(numpy.random.randn(nrow, ncol),
        12     66.77 MB    7.58 MB                             index = numpy.random.randn(nrow),
        13     90.46 MB   23.70 MB                             columns = list(string.letters[0:ncol]))
        14    114.96 MB   24.49 MB       df_new = df[from_:to_].copy()
        15    114.96 MB    0.00 MB       del df
        16     90.54 MB  -24.42 MB       del df_new
        17     52.39 MB  -38.15 MB       gc.collect()
    

    실제로 우리가 시작할 때보 다 더 많은 메모리가 사용됩니다. 그러나 그것이 새고 있습니까?

    for _ in xrange(20):
        test()
        print mprof.memory_usage()
    

    그리고 출력 :

    10:19 ~/tmp $ python profmem.py 
    [52.3984375]
    [122.59375]
    [122.59375]
    [122.59375]
    [122.59375]
    [122.59375]
    [122.59375]
    [122.59375]
    [122.59375]
    [122.59375]
    [122.59375]
    [122.59375]
    [122.59375]
    [122.59375]
    [122.59375]
    [122.59375]
    [122.59375]
    [122.59765625]
    [122.59765625]
    [122.59765625]
    

    따라서 실제로 진행된 작업은 파이썬 프로세스가 호스트 OS에서 더 많은 메모리를 요청한 다음 (그리고 해제하는) 피하기 위해 사용 된 메모리 풀을 유지하는 것입니다. 나는 이것의 뒤에 모든 기술적 인 세부 사항을 모른다, 그러나 그것은 적어도 무슨 일이 일어나고있는가이다.

  2. from https://stackoverflow.com/questions/10601041/pandas-wheres-the-memory-leak-here by cc-by-sa and MIT license