#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
это.