私は、データにNaN
がないことを確認して、もう一度CSVとして別の列サブセットを出力しなければならない40GBのCSVファイルを持っています。私はパンダを使用することを選んだ、と私の実装の最小限の例では、この(機能output_different_formats
内側)のようになります。40GバイトのCSVを読み書きするときのMemoryError ...どこにリークがありますか?
# column_names is a huge list containing the column union of all the output
# column subsets
scen_iter = pd.read_csv('mybigcsv.csv', header=0, index_col=False,
iterator=True, na_filter=False,
usecols=column_names)
CHUNKSIZE = 630100
scen_cnt = 0
output_names = ['formatA', 'formatB', 'formatC', 'formatD', 'formatE']
# column_mappings is a dictionary mapping the output names to their
# respective column subsets.
while scen_cnt < 10000:
scenario = scen_iter.get_chunk(CHUNKSIZE)
if scenario.isnull().values.any():
# some error handling (has yet to ever occur)
for item in output_names:
scenario.to_csv(item, float_format='%.8f',
columns=column_mappings[item],
mode='a', header=True, index=False, compression='gzip')
scen_cnt+=100
私は.get_chunk()
とチャンク内のファイルを反復処理していますように私は、これは安全なメモリ単位だと思いました一度にDataFrameにCSV全体を配置することはなく、それぞれのファイルの最後に次のチャンクを追加するだけです。
File "D:\AppData\A\MRM\Eric\Anaconda\lib\site-packages\pandas\core\common.py", line 838, in take_nd
out = np.empty(out_shape, dtype=dtype)
MemoryError
で終わると.to_csv
ラインで次のMemoryErrorで墜落しましたか?プログラムのどこかにメモリリークがあるのですか、何かを誤解していますか?あるいは、その特定のチャンクのためにCSVへの書き込みをランダムに失敗するようにプログラムを誘惑することができますか?チャンクサイズを減らすことを検討するべきでしょうか?
完全トレースバック:
Traceback (most recent call last):
File "D:/AppData/A/MRM/Eric/output_formats.py", line 128, in <module>
output_different_formats(real_world=False)
File "D:/AppData/A/MRM/Eric/output_formats.py", line 50, in clocked
result = func(*args, **kwargs)
File "D:/AppData/A/MRM/Eric/output_formats.py", line 116, in output_different_formats
mode='a', header=True, index=False, compression='gzip')
File "D:\AppData\A\MRM\Eric\Anaconda\lib\site-packages\pandas\core\frame.py", line 1188, in to_csv
decimal=decimal)
File "D:\AppData\A\MRM\Eric\Anaconda\lib\site-packages\pandas\core\format.py", line 1293, in __init__
self.obj = self.obj.loc[:, cols]
File "D:\AppData\A\MRM\Eric\Anaconda\lib\site-packages\pandas\core\indexing.py", line 1187, in __getitem__
return self._getitem_tuple(key)
File "D:\AppData\A\MRM\Eric\Anaconda\lib\site-packages\pandas\core\indexing.py", line 720, in _getitem_tuple
retval = getattr(retval, self.name)._getitem_axis(key, axis=i)
File "D:\AppData\A\MRM\Eric\Anaconda\lib\site-packages\pandas\core\indexing.py", line 1323, in _getitem_axis
return self._getitem_iterable(key, axis=axis)
File "D:\AppData\A\MRM\Eric\Anaconda\lib\site-packages\pandas\core\indexing.py", line 966, in _getitem_iterable
result = self.obj.reindex_axis(keyarr, axis=axis, level=level)
File "D:\AppData\A\MRM\Eric\Anaconda\lib\site-packages\pandas\core\frame.py", line 2519, in reindex_axis
fill_value=fill_value)
File "D:\AppData\A\MRM\Eric\Anaconda\lib\site-packages\pandas\core\generic.py", line 1852, in reindex_axis
{axis: [new_index, indexer]}, fill_value=fill_value, copy=copy)
File "D:\AppData\A\MRM\Eric\Anaconda\lib\site-packages\pandas\core\generic.py", line 1876, in _reindex_with_indexers
copy=copy)
File "D:\AppData\A\MRM\Eric\Anaconda\lib\site-packages\pandas\core\internals.py", line 3157, in reindex_indexer
indexer, fill_tuple=(fill_value,))
File "D:\AppData\A\MRM\Eric\Anaconda\lib\site-packages\pandas\core\internals.py", line 3238, in _slice_take_blocks_ax0
new_mgr_locs=mgr_locs, fill_tuple=None))
File "D:\AppData\A\MRM\Eric\Anaconda\lib\site-packages\pandas\core\internals.py", line 853, in take_nd
allow_fill=False)
File "D:\AppData\A\MRM\Eric\Anaconda\lib\site-packages\pandas\core\common.py", line 838, in take_nd
out = np.empty(out_shape, dtype=dtype)
MemoryError
ループ内のガベージコレクタ( 'gc.collect()')を呼び出そうとするかもしれません。回避策として、64ビットバージョンのPythonを試すこともできます。 –
@ Jean-FrançoisFabre 'gc.collect()'を使って試してみると、それがもう数時間で成功したかどうかはわかりません。 64ビットPythonがなぜ役立つのでしょうか? –
64ビットのPythonでは、より多くのメモリ割り当てが可能です(もちろん、システム上の物理メモリとスワップ、64ビットのウィンドウが必要です)。これはメモリリークを修正するものではありませんが、プログラムが終了するまで遅くなります。 –