2016-07-04 30 views
1

私は多分可能または多分別の方法で行われるべきではない何かをやろうとしている...メモリエラーが

私は1ギガバイトのアクセスを読む必要がありパンダでファイルし、操作する。 が直接Memory Errorで失敗したので、私はメモリエラーが発生したことを確認するために以下の関数を試しました:400.000行がフェッチされた後に表示されます(合計は1.12Mrowsです)。

私のマシンに8GBのRAMがあり、それは50%で無料と思われるので奇妙です。私も仮想メモリを16 GBに設定しましたが、結果は変わりませんでした。

私は微積分のスピードを必要としません。そのため、ハードディスクをラム(私はssdを持っています)として使用することを含め、どんな汚れた解決策も歓迎します。

多分、すべてのメモリをpythonで利用できるようにする方法がありますか?

  • 単一行フェッチ:cursor.fetchone()
  • 多くの行をフェッチ:cursor.fetchmany()
  • すべての行がフェッチ:cursor.fetchall()
  • パンダread_sqlchunksize渡し:pandas.read_sql(query, conn, chunksize=chunksize)(THXをすでに失敗している

    つの方法ユーザMaxU)

機能:

def msaccess_to_df (abs_path, query): 
    conn = pypyodbc.connect(
     r"Driver={Microsoft Access Driver (*.mdb, *.accdb)};" 
     r"Dbq=" + abs_path + ";") 

    cur = conn.cursor() 
    cur.execute(query) 

    fields = zip(*cur.description)[0] 
    df = pandas.DataFrame(columns=fields) 

    fetch_lines_per_block = 5000 
    i = 0 
    while True: 
     rows = cur.fetchmany(fetch_lines_per_block) # <----- 
     if len(rows) == 0: break 
     else: 
      rd = [dict(zip(fields, r)) for r in rows] 
      df = df.append(rd, ignore_index=True) 
      del rows 
      del rd 
     i+=1 
     print 'fetched', i*fetch_lines_per_block, 'lines' 

    cur.close() 
    conn.close() 

    return df 

ERROR:

df = df.append(rd, ignore_index=True) 
    File "C:\Python27\lib\site-packages\pandas\core\frame.py", line 4338, in append 
    verify_integrity=verify_integrity) 
    File "C:\Python27\lib\site-packages\pandas\tools\merge.py", line 845, in concat 
    copy=copy) 
    File "C:\Python27\lib\site-packages\pandas\tools\merge.py", line 904, in __init__ 
    obj.consolidate(inplace=True) 
    File "C:\Python27\lib\site-packages\pandas\core\generic.py", line 2747, in consolidate 
    self._consolidate_inplace() 
    File "C:\Python27\lib\site-packages\pandas\core\generic.py", line 2729, in _consolidate_inplace 
    self._protect_consolidate(f) 
    File "C:\Python27\lib\site-packages\pandas\core\generic.py", line 2718, in _protect_consolidate 
    result = f() 
    File "C:\Python27\lib\site-packages\pandas\core\generic.py", line 2727, in f 
    self._data = self._data.consolidate() 
    File "C:\Python27\lib\site-packages\pandas\core\internals.py", line 3273, in consolidate 
    bm._consolidate_inplace() 
    File "C:\Python27\lib\site-packages\pandas\core\internals.py", line 3278, in _consolidate_inplace 
    self.blocks = tuple(_consolidate(self.blocks)) 
    File "C:\Python27\lib\site-packages\pandas\core\internals.py", line 4269, in _consolidate 
    _can_consolidate=_can_consolidate) 
    File "C:\Python27\lib\site-packages\pandas\core\internals.py", line 4292, in _merge_blocks 
    new_values = new_values[argsort] 
MemoryError 

#################### EDIT - 解決しよう####################

最後に、私は

で解決しました

でアクセスドライバを交換Pythonの64ビット

  • のインストール16ギガバイト
  • にマシンの仮想メモリを設定します。

    def msaccess_to_df (abs_path, query): 
        conn = pypyodbc.connect(
         r"Driver={Microsoft Access Driver (*.mdb, *.accdb)};" 
         r"Dbq=" + abs_path + ";") 
    
        df = pd.read_sql(query, conn) 
        conn.close() 
        return df 
    

    それでもMemoryError例外を受信して​​いる場合、チャンクでデータを読み取ろう:

    def msaccess_to_df (abs_path, query, chunksize=10**5): 
        conn = pypyodbc.connect(
         r"Driver={Microsoft Access Driver (*.mdb, *.accdb)};" 
         r"Dbq=" + abs_path + ";") 
    
        df = pd.concat([x for x in pd.read_sql(query, conn, chunksize=chunksize)], 
            ignore_index=True) 
        conn.close() 
        return df 
    

    代わりに、ループ内で手動で行をフェッチするのread_sql() -

  • +1

    Ah!あなたのマシンが許可している場合は、ちょうどPython 64ビットをお勧めします。将来の読者のためにあなたの編集を回答として投稿してください。 – Parfait

    答えて

    1

    私は、ネイティブパンダメソッドを使用しますPSこれはあなたにアイデアを与えるはずですが、私はこのコードをテストしなかったので、デバッグが必要かもしれないことに注意してください。

    +0

    ありがとうございますが、 'chunksize'でも3GB RAMを無料(Windowsリソースモニタで表示)しても、しばらくしてもメモリエラーが表示されます。 – DPColombotto