2012-05-15 8 views
11

pandasライブラリpythonでメモリリークの問題に直面します。私は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() 
  • 。 67メガバイト

  • をサイズ変更した後 - - 縮小テーブルを削除した後

  • 35MB - - 元のデータフレームを削除した後に67メガバイト

  • を作成した後、メモリ使用量の15メガバイト

  • 31メガバイト

16mb?

Windows 7(x64)マシンのpandasでpython 2.7.2(x32)を使用しています。 バージョンは0.7.3です。数が少ない。 バージョンが指摘する1.6.1

+0

これはPythonのメモリ割り当ての仕組みです。おそらくメモリリークはありません。 – jozzas

答えて

26

カップルの事である:「サイズを変更した後にメモリをチェックしてください」で

  1. 、あなたはまだ、元のデータフレームを削除していないので、これは厳密に使用されますmore memory

  2. Pythonインタプリタは、OSメモリを保持することについて少し貪欲です。

私はこれを調べて、パンダが記憶を漏らしていないことを確認できます。私は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] 

だから、実際に行って何Pythonのプロセスは、より多くのメモリを要求して維持することを避けるために使用されているもの与えられたメモリのプールにつかまっ(とされていることですその後、ホストOSから解放します)。私はこれの背後にあるすべての技術的な詳細を知らないが、それは少なくとも起こっていることである。

関連する問題