87

大きなcsvファイルをパンダのデータフレームに読み込むという、かなり単純なことをしようとしています。

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

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

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

私はパンダバージョン0.11.0を使用しています。

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

読み込もうとしているファイルは 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 がそのサイズのファイルに問題がある場合、私は負け戦を戦っているかもしれません...

4

8 に答える 8

32

Windows メモリの制限

Windows で 32 ビット版を使用すると、Python でメモリ エラーが頻繁に発生します。これは、32 ビット プロセスがデフォルトで 2GB のメモリしか使用できないためです。

メモリ使用量を下げるためのトリック

Windows で 32 ビット Python を使用していないが、csv ファイルを読み取る際のメモリ効率を改善したい場合は、1 つのトリックがあります。

pandas.read_csv 関数は、というオプションを取りますdtype。これにより、パンダは 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 が dtype オプションなしで上記の csv ファイルを読み取った場合、pandas が適切な推測を行うのに十分な行数の csv ファイルを読み取るまで、年齢が文字列としてメモリに格納されます。

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

解決

dtype={'age':int}willのオプションとして指定する.read_csv()ことで、年齢を数値として解釈する必要があることを 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

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

ここでは、float が文字列として保持されている場合に、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)
于 2015-07-21T14:14:02.710 に答える
2

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

于 2015-03-10T08:13:01.673 に答える
1

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

あなたが持っている唯一のチャンスは、あなたがすでに試したことであり、大きなものをメモリに収まる小さな断片に切り刻むようにしてください.

MapReduce とは何かを自問したことがあるなら、あなたは自分でそれを発見したでしょう... MapReduce は多くのマシンにチャンクを分散しようとし、1 台のマシンで次々とチャンクを処理しようとします。

チャンクファイルの連結でわかったことは、実際には問題になる可能性があります。おそらく、この操作で必要なコピーがあるかもしれません...しかし、最終的には、これで現在の状況で節約できるかもしれませんが、csvが少し大きくなった場合またあの壁にぶつかるかもしれない…

また、パンダは非常にスマートなので、大きな df に連結するなど、何かを行うと、実際には個々のデータチャンクのみがメモリにロードされる可能性がありますか?

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

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

Pandas 0.12.0 と NumPy 1.8.0 ではエラーはありません。

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

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

于 2014-02-04T14:51:37.527 に答える
-1

これは修正というほどの回避策ではありませんが、その CSV を JSON に変換し (簡単なはずです)、read_json代わりにメソッドを使用してみてください。全く問題のない方法。

于 2014-01-02T09:03:08.090 に答える