Потеря памяти Панд Питона

#python #pandas #jupyter-notebook

Вопрос:

У меня есть проблема с потерей памяти python/pandas при чтении файлов рассола (в цикле) или файлов паркета. Я попытался проанализировать это с помощью профилировщика памяти. Результаты следующие:

 Filename: /home/ubuntu/work/a4lbs/src/analyze/load.py

Line #    Mem usage    Increment  Occurences   Line Contents
============================================================
   269    265.2 MiB    265.2 MiB           1   def load():

[…]
290    269.5 MiB      0.0 MiB           1       dataframes = []
   291  13328.4 MiB      0.0 MiB          24       for month in months:
   292                                         
   293                                                 # Try to find data source file and skip it if not present
   294  13289.5 MiB      0.0 MiB          23           picklefilename = partnr   month   "_.pickle.gz"
   295                                         
   296                                         
   297                                                 # Check if cached file exists and is up to date, update otherwise
   298  13289.5 MiB      0.1 MiB          23           picklefilepath = cache.cache_file(input_root_path, pickle_subpath, picklefilename)
   299  13289.5 MiB      0.0 MiB          23           if not len(picklefilepath):
   300                                                     continue
   301                                         
   302                                                 # finally read source file
   303  13289.5 MiB      0.0 MiB          23           log("Reading "   month   " from "   picklefilename   "...", end='')
   304  13289.5 MiB      0.0 MiB          23           dataframes.append(
   305  13289.5 MiB      0.0 MiB          23               pd.read_pickle(
   306  13289.5 MiB      0.0 MiB          23                   picklefilepath,
   307  13328.4 MiB  13058.8 MiB          23                   compression="gzip",
   308                                                     )  ## READ
   309                                                 )
   310  13328.4 MiB      0.0 MiB          23           print(" done.")
   311  14577.0 MiB   1248.6 MiB           1       df_data = pd.concat(dataframes, sort=False)  # merge into 1 dataframe
   312  14382.3 MiB   -194.7 MiB           1       dataframes.clear()
   313                                         
   314  14382.3 MiB      0.0 MiB           1       precipitation_data_filename = partnr   "_precipitation_data.parquet"
   315  14382.3 MiB      0.0 MiB           1       precipitation_data_subpath = "/".join((HERE_weather_subpath, partnr))
   316  14382.3 MiB      0.0 MiB           1       print()
   317  14382.3 MiB      0.0 MiB           1       precipitation_data_filepath = cache.cache_file(input_root_path, precipitation_data_subpath, precipitation_data_filename)
   318  14382.3 MiB      0.0 MiB           1       log("Reading precipitation data from "   precipitation_data_filename   "...", end='')
   319  27918.5 MiB  13536.3 MiB           1       prec_df = pq.read_table(precipitation_data_filepath).to_pandas()
   320  27918.5 MiB      0.0 MiB           1       print(" done.")
 

В основном 2 вопроса:
Строка 307: Массив «кадры данных» требует 13 ГБ при чтении, но
Строка 312: когда я ее очищаю, я получаю только 194 МБ. Я также пробую gc.collect() — результат не изменился.
Строка 319: Для чтения в prec_df также требуется 13 ГБ, но самому фрейму данных требуется всего 5 ГБ:
введите описание изображения здесь

Мне кажется, что сам процесс чтения файлов требует дополнительной памяти, которая больше не возвращается?

Спасибо за любую помощь! Оливер

Ответ №1:

memory_usage() Функция Панд не является надежным показателем использования памяти. Как минимум, вам нужен deep=True аргумент, но даже в этом случае он может не отслеживать всю память.

В качестве альтернативы memory_profiler вы можете попробовать https://pythonspeed.com/fil, что дает вам другое представление об использовании памяти. Это может прояснить, где именно выделяется память, в том числе по другим причинам, потому что это не связано просто с сообщением об одном модуле, как memory_profiler это.