Кажется, что pandas запускает утечку памяти, когда iteritavely копирует значение из кадра данных.Утечка памяти при чтении значения из фрейма данных Pandas
В начале каждой итерации создается кадр данных, создавая копию из исходного кадра данных. Вторая переменная создается путем копирования одного значения из текущего фрейма данных.
В конце каждой итерации эти две переменные удаляются, а память, используемая текущим процессом, печатается (на каждые 1000 итераций). used memory increases!
Я думаю, что в какой-то момент может быть какая-то неявная копия (возможно, при чтении значения dataframe).
Быстрое исправление этой проблемы приводит к применению сборщика мусора на каждой итерации, но это довольно дорогое решение: процесс по меньшей мере в 10 раз медленнее.
Есть ли четкое объяснение причин возникновения этой проблемы?
import os, gc
import psutil, pandas as pd
N_ITER = 100000
DF_SIZE = 10000
# Define the DataFrame
df = pd.DataFrame(index=range(DF_SIZE), columns=['my_col'])
df['my_col'] = range(DF_SIZE)
def memory_usage():
"""Return the memory usage of the current python process."""
return psutil.Process(os.getpid()).memory_info().rss/1024 ** 2
if __name__ == '__main__':
for i in range(N_ITER):
df_ind = pd.DataFrame(df.copy())
val = df_ind.at[4242, 'my_col'] # The line that provokes the leak!
del df_ind, val # Useless
# gc.collect() # Garbage Collector prevents the leak but is slow
if (i % 1000) == 0:
print('Iter {}\t {} MB'.format(i, int(memory_usage())))
Если вы звоните 'GC.Collect()' освобождает память, то это это совершенно нормальное и ожидаемое поведение. Есть некоторая круговая ссылка где-то мешает механизму ref-counting освободить память. Просто запустите свою программу; если слишком много невостребованных, претенциозных объектов накапливаются, GC автоматически запускается и очищает их. – user2357112
Спасибо за ваш ответ. Я позволю запустить код, а затем подожду и посмотрю. Как вы могли бы предотвратить эти циркулярные ссылки? –
Это должно быть сделано в реализации Pandas. – user2357112