Мне было интересно... Если я читаю, скажем, 400-мегабайтный CSV файл в pandas dataframe (используя read_csv или read_table), есть ли способ оценить, сколько памяти это понадобится? Просто пытаясь получить лучшее представление о кадрах данных и памяти...
Как оценить объем памяти Pandas 'DataFrame?
Ответ 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 файлом в зависимости от количества строк. (Размер в мегабайтах)
Второй эксперимент имел тот же подход, но данные в наборе данных состояли только из коротких строк.
Похоже, что отношение размера 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