web-dev-qa-db-ja.com

pandas read_csvを使用する場合のメモリエラー

大きなcsvファイルをpandasデータフレームに読み込んで、かなり簡単なことをしようとしています。

data = pandas.read_csv(filepath, header = 0, sep = DELIMITER,skiprows = 2)

コードはMemoryErrorで失敗するか、終了しません。

タスクマネージャでのメモリ使用量は506 Mbで停止し、5分間変更がなく、プロセスでCPUアクティビティがなくなった後、停止しました。

pandasバージョン0.11.0を使用しています。

以前はファイルパーサーにメモリの問題があったことを認識していますが、http://wesmckinney.com/blog/?p=54これは修正されているはずです。

読み込もうとしているファイルは366 Mbです。ファイルを短い(25 Mb)に切り詰めると、上記のコードは機能します。

また、アドレス0x1e0baf93に書き込めないことを知らせるポップアップが表示されることもありました...

スタックトレース:

Traceback (most recent call last):
  File "F:\QA ALM\Python\new WIM data\new WIM data\new_WIM_data.py", line 25, in
 <module>
    wimdata = pandas.read_csv(filepath, header = 0, sep = DELIMITER,skiprows = 2
)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\io\parsers.py"
, line 401, in parser_f
    return _read(filepath_or_buffer, kwds)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\io\parsers.py"
, line 216, in _read
    return parser.read()
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\io\parsers.py"
, line 643, in read
    df = DataFrame(col_dict, columns=columns, index=index)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\frame.py"
, line 394, in __init__
    mgr = self._init_dict(data, index, columns, dtype=dtype)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\frame.py"
, line 525, in _init_dict
    dtype=dtype)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\frame.py"
, line 5338, in _arrays_to_mgr
    return create_block_manager_from_arrays(arrays, arr_names, axes)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\internals
.py", line 1820, in create_block_manager_from_arrays
    blocks = form_blocks(arrays, names, axes)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\internals
.py", line 1872, in form_blocks
    float_blocks = _multi_blockify(float_items, items)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\internals
.py", line 1930, in _multi_blockify
    block_items, values = _stack_arrays(list(tup_block), ref_items, dtype)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\internals
.py", line 1962, in _stack_arrays
    stacked = np.empty(shape, dtype=dtype)
MemoryError
Press any key to continue . . .

少しの背景-私はPythonがRと同じことをできると人々に納得させようとしています。このために、Rスクリプトを複製しようとしています。

data <- read.table(paste(INPUTDIR,config[i,]$TOEXTRACT,sep=""), HASHEADER, DELIMITER,skip=2,fill=TRUE)

Rは上記のファイルをうまく読み込めるだけでなく、これらのファイルのいくつかをforループで読み取ります(そしてデータを処理します)。 Pythonがそのサイズのファイルで問題を抱えている場合、私は負けた戦いと戦っているかもしれません...

78
Anne

Windowsメモリの制限

Windowsで32ビットバージョンを使用すると、pythonでメモリエラーが頻繁に発生します。これは、32ビットプロセス 遊ぶために2GBのメモリのみを取得 がデフォルトであるためです。

メモリ使用量を減らすための秘Tri

Windowsで32ビットpythonを使用していないが、csvファイルの読み取り中にメモリ効率を改善しようとしている場合、トリックがあります。

pandas.read_csv関数 は、dtypeというオプションを取ります。これにより、pandasがcsvデータ内に存在する型を知ることができます。

仕組み

デフォルトでは、pandasは、csvファイルのdtypeを推測しようとします。 dtypeを決定している間、すべての生データをオブジェクト(文字列)としてメモリに保持する必要があるため、これは非常に重い操作です。

あなたのcsvがこのように見えるとしましょう:

name, age, birthday
Alice, 30, 1985-01-01
Bob, 35, 1980-01-01
Charlie, 25, 1990-01-01

もちろん、この例はメモリに読み込むのに問題はありませんが、単なる例です。

pandasが上記のcsvファイルなしでdtypeオプションを読み取る場合、年齢はpandascsvファイルの十分な行を読み取って、適切な推測を行いました。

pandasのデフォルトは、dtypeを推測する前に1,000,000行を読み取ることだと思います。

解決

.read_csv()のオプションとしてdtype={'age':int}を指定することにより、年齢を数値として解釈する必要があることをpandasに通知します。これにより、多くのメモリを節約できます。

破損したデータの問題

ただし、次のようにcsvファイルが破損する場合:

name, age, birthday
Alice, 30, 1985-01-01
Bob, 35, 1980-01-01
Charlie, 25, 1990-01-01
Dennis, 40+, None-Ur-Bz

dtype={'age':int}をintにキャストできないため、"40+"を指定すると.read_csv()コマンドが壊れます。データを慎重にサニタイズしてください!

ここでは、フロートが文字列として保持されている場合、pandasデータフレームのメモリ使用量がはるかに高いことがわかります。

自分で試してみてください

df = pd.DataFrame(pd.np.random.choice(['1.0', '0.6666667', '150000.1'],(100000, 10)))
resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
# 224544 (~224 MB)

df = pd.DataFrame(pd.np.random.choice([1.0, 0.6666667, 150000.1],(100000, 10)))
resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
# 79560 (~79 MB)
30
firelynx

サイズが約1 GB(550万件を超えるレコード)のタブ区切りテキストファイルの単純な読み取りで同じメモリの問題が発生し、これによりメモリの問題が解決しました。

df = pd.read_csv(myfile,sep='\t') # didn't work, memory error
df = pd.read_csv(myfile,sep='\t',low_memory=False) # worked fine and in less than 30 seconds

Spyder 3.2.3 Python 2.7.13 64ビット

4
mooseman

LinuxボックスでPandasを使用していますが、githubからクローンを作成した後、Pandasを最新バージョンにアップグレードした後にのみ解決される多くのメモリリークに直面しました。

3
Tarik

Pandas 0.12.0およびNumPy 1.8.0にはエラーはありません。

大きなDataFrameを作成してcsvファイルに保存し、正常に読み取ることができました。例を参照してください here 。ファイルのサイズは554 Mbです(1.1 Gbファイルでも動作し、30秒の1.1Gbファイル使用頻度を生成するのに時間がかかりました)。 4GbのRAMが利用可能ですが。

私の提案は、パンダを更新してみることです。 Rの場合はVisual Studioを使用していないため、コマンドラインからスクリプトを実行してみてください(これは既に質問へのコメントで提案されています)。

2
Oleksandr

この問題は、仮想マシンで実行しているときや、メモリが大幅に制限されている場所でも発生しました。 pandasまたはnumpyまたはcsvとは関係ありませんが、Pythonだけでなく、使用を許可されているためにメモリをさらに使用しようとすると常に発生します。

あなたが持っている唯一のチャンスは、あなたがすでに試したことです。記憶に収まる小さな断片に大きなものを切り詰めてみてください。

MapReduceとは何かを自問した場合、自分で見つけた... MapReduceはチャンクを多数のマシンに分散しようとし、1つのマシンでチャンクを次々に処理しようとします。

あなたがチャンクファイルの連結で見つけたものは確かに問題かもしれません、おそらくこの操作にいくつかのコピーが必要かもしれません...しかし、最終的にこれはあなたの現在の状況であなたを救うかもしれませんが、csvが少し大きくなるとあなたはその壁に再び走るでしょう...

また、pandasは非常にスマートで、実際に個々のデータチャンクをメモリにロードするのは、大きなdfに連結するなど、何かを行う場合だけでしょうか。

あなたが試すことができるいくつかのこと:

  • すべてのデータを一度にロードしないで、分割してください
  • 私の知る限り、hdf5はこれらのチャンクを自動的に実行し、プログラムが現在動作している部分のみをロードします
  • 型が大丈夫かどうかを確認してください。文字列 '0.111111'はfloatよりも多くのメモリを必要とします
  • 実際に必要なものは、文字列としてのアドレスがある場合、数値分析には必要ないかもしれません...
  • データベースは、実際に必要な部分(たとえば、1%のアクティブユーザーのみ)にアクセスしてロードするのに役立ちます。
1

これは修正ではなく回避策ですが、そのCSVをJSONに変換し(簡単なはずです)、代わりにread_jsonメソッドを使用してみます-かなりのJSON /データフレーム(100のMB)Pandasで、このようにまったく問題なく。

0
LetMeSOThat4U

大きなCSVファイルの読み取り中にchunksizeを試しました

reader = pd.read_csv(filePath,chunksize=1000000,low_memory=False,header=0)

読み取りがリストになりました。 readerを繰り返し、新しいcsvに書き込み/追加するか、任意の操作を実行できます。

for chunk in reader:
    print(newChunk.columns)
    print("Chunk -> File process")
    with open(destination, 'a') as f:
        newChunk.to_csv(f, header=False,sep='\t',index=False)
        print("Chunk appended to the file")
0
muTheTechie