Подтвердить что ты не робот

Как оценить объем памяти Pandas 'DataFrame?

Мне было интересно... Если я читаю, скажем, 400-мегабайтный CSV файл в pandas dataframe (используя read_csv или read_table), есть ли способ оценить, сколько памяти это понадобится? Просто пытаясь получить лучшее представление о кадрах данных и памяти...

4b9b3361

Ответ 1

df.memory_usage() вернет, сколько занимает каждый столбец:

>>> df.memory_usage()

Row_ID            20906600
Household_ID      20906600
Vehicle           20906600
Calendar_Year     20906600
Model_Year        20906600
...

Чтобы включить индексы, пройдите index=True.

Итак, чтобы получить общее потребление памяти:

>>> df.memory_usage(index=True).sum()
731731000

Кроме того, передача memory_usage = 'deep' позволит получить более точный отчет об использовании памяти, который учитывает полное использование содержащихся объектов.

Это связано с тем, что использование памяти не включает в себя память, потребляемую элементами, которые не являются компонентами массива, если deep = False (случай по умолчанию).

Ответ 2

Вы должны сделать это обратным образом.

In [4]: DataFrame(randn(1000000,20)).to_csv('test.csv')

In [5]: !ls -ltr test.csv
-rw-rw-r-- 1 users 399508276 Aug  6 16:55 test.csv

Техническая память об этом (включая индексы)

In [16]: df.values.nbytes + df.index.nbytes + df.columns.nbytes
Out[16]: 168000160

Итак, 168 МБ в памяти с файлом 400 Мбайт, 1М строк из 20 столбцов с плавающей запятой

DataFrame(randn(1000000,20)).to_hdf('test.h5','df')

!ls -ltr test.h5
-rw-rw-r-- 1 users 168073944 Aug  6 16:57 test.h5

MUCH более компактный при записи в виде двоичного файла HDF5

In [12]: DataFrame(randn(1000000,20)).to_hdf('test.h5','df',complevel=9,complib='blosc')

In [13]: !ls -ltr test.h5
-rw-rw-r-- 1 users 154727012 Aug  6 16:58 test.h5

Данные были случайными, поэтому сжатие не очень помогает

Ответ 3

Я думал, что принесу еще несколько данных для обсуждения.

Я провела серию тестов по этой проблеме.

Используя пакет python resource, я получил использование памяти в моем процессе.

И, написав csv в буфере StringIO, я мог бы легко измерить его размер в байтах.

Я провел два эксперимента, каждый из которых создавал 20 информационных кадров с увеличением размеров между 10000 строк и 1 000 000 строк. Оба имеют 10 столбцов.

В первом эксперименте я использовал только float в моем наборе данных.

Таким образом, память увеличилась по сравнению с CSV файлом в зависимости от количества строк. (Размер в мегабайтах)

Memory and CSV size in Megabytes as a function of the number of rows with float entries

Второй эксперимент имел тот же подход, но данные в наборе данных состояли только из коротких строк.

Memory and CSV size in Megabytes as a function of the number of rows with string entries

Похоже, что отношение размера csv и размера блока данных может варьироваться довольно много, но размер в памяти всегда будет больше в 2-3 раза (для размеров кадра в этом эксперименте )

Я хотел бы завершить этот ответ с большим количеством экспериментов, прокомментируйте, если вы хотите, чтобы я попробовал что-то особенное.

Ответ 4

Если вы знаете dtype вашего массива, вы можете напрямую вычислить количество байтов, которое потребуется для хранения ваших данных + некоторые для самих объектов Python. Полезным атрибутом массива numpy является nbytes. Вы можете получить количество байтов из массивов в pandas DataFrame, выполнив

nbytes = sum(block.values.nbytes for block in df.blocks.values())

object массивы dtype хранят 8 байтов на объект (массивы dtype объекта хранят указатель на непрозрачный PyObject), поэтому, если у вас есть строки в вашем csv, вам нужно учитывать, что read_csv превратит их в object dtype и соответствующим образом скорректируйте свои расчеты.

EDIT:

Подробнее о object dtype см. на странице numpy скалярных типов. Поскольку хранится только эта ссылка, вам нужно также учитывать размер объекта в массиве. Как говорит эта страница, массивы объектов несколько похожи на объекты Python list.

Ответ 5

Да, есть. Pandas будет хранить ваши данные в 2-мерных numpy ndarray структурах, группирующих их по dtypes. ndarray - это в основном исходный массив данных C с небольшим заголовком. Таким образом, вы можете оценить его размер, просто умножив размер dtype, который он содержит, с размерами массива.

Например: если у вас 1000 строк с 2 столбцами np.int32 и 5 np.float64, ваш DataFrame будет иметь один массив 2x1000 np.int32 и один массив 5x1000 np.float64, который:

4 байта * 2 * 1000 + 8bytes * 5 * 1000 = 48000 байт

Ответ 6

Это я считаю, что это дает размер памяти в памяти любого объекта в python. Внутренние элементы должны быть проверены в отношении pandas и numpy

>>> import sys
#assuming the dataframe to be df 
>>> sys.getsizeof(df) 
59542497

Ответ 7

Сравнение различных методов

df - это dataframe с 814 строками, 11 столбцами (2 ints, 9 объектов) - чтение из файла формы размером 427kb

df.info()

>>> df.info()
...
memory usage: 70.0+ KB

>>> df.info(memory_usage='deep')
...
memory usage: 451.6 KB

df.memory_usage()

>>> df.memory_usage()
...
(lists each column at 8 bytes/row)

>>> df.memory_usage().sum()
71712
(roughly rows * cols * 8 bytes)

>>> g.memory_usage(deep=True)
(lists each column full memory usage)

>>> g.memory_usage(deep=True).sum()
462432

sys.getsizeof(DF)

>>> import sys
>>> sys.getsizeof(df)
462456