Ich habe eine 40GB CSV-Datei, die ich mit verschiedenen Spaltenuntergruppen als CSVs wieder ausgeben muss, mit einer Überprüfung, dass es keine NaN
s in den Daten gibt. Ich entschied ich Pandas, und ein minimales Beispiel für meine Implementierung sieht wie folgt aus zu verwenden (in einer Funktion output_different_formats
):MemoryError beim Lesen und Schreiben einer 40 GB CSV ... wo ist mein Leck?
# 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
ich gedacht war sicher Speicher-weise, wie ich über die Datei in Brocken am Iterieren mit .get_chunk()
und legen Sie niemals die gesamte CSV-Datei gleichzeitig in einen DataFrame, sondern fügen Sie einfach den nächsten Chunk an das Ende der jeweiligen Datei an.
jedoch etwa 3,5 GBs in die Ausgang Generation, stürzte mein Programm mit dem folgende Memory in der .to_csv
Linie mit einem langen Traceback mit den folgenden
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
Warum bin ich hier ein Memory bekommen? Habe ich irgendwo in meinem Programm ein Speicherleck oder verkenne ich etwas? Oder könnte das Programm dazu gebracht werden, beim Schreiben in die CSV-Datei für diesen bestimmten Block nur zufällig fehlzuschlagen, und vielleicht sollte ich erwägen, die Chunksize zu reduzieren?
Volltraceback:
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
Vielleicht könnten Sie versuchen, den Garbage Collector in der Schleife aufzurufen ('gc.collect()'). Als Workaround können Sie auch eine 64-Bit-Version von Python ausprobieren. –
@ Jean-FrançoisFabre Wenn ich jetzt mit 'gc.collect()' versuche, weiß ich nicht, ob es noch ein paar Stunden erfolgreich war. Warum könnte 64-Bit-Python helfen? –
64-Bit-Python ermöglicht mehr Speicherzuweisung (natürlich benötigen Sie den physischen Speicher/Swap auf Ihrem System und ein 64-Bit-Windows). Dies wird das Speicherleck nicht beheben, wird es aber hoffentlich bis zur Beendigung Ihres Programms verzögern. –