Мне было интересно ... Если я читаю, скажем, файл csv размером 400 МБ в фрейм данных pandas (с использованием read_csv или read_table), есть ли способ предположить, сколько памяти для этого потребуется? Просто пытаюсь лучше понять фреймы данных и память ...
126
top
затемShift + M
отсортировать использование моей памяти.x=df.loc[[]]
занимает0.1
секунды , чтобы вычислить (для извлечения нулевых строк) и, кроме того, занимает сотню мегабайта памяти, так же , как оригинал dataframe, вероятно , из - за некоторое копирование внизу.Ответы:
df.memory_usage()
вернет, сколько занимает каждый столбец:Чтобы включить индексы, пройдите
index=True
.Итак, чтобы получить общее потребление памяти:
Кроме того, передача
deep=True
позволит составить более точный отчет об использовании памяти, который учитывает полное использование содержащихся объектов.Это связано с тем, что использование памяти не включает память, потребляемую элементами, которые не являются компонентами массива if
deep=False
(случай по умолчанию).источник
deep=True
deep=True
memory_usage()
возвращает использование памяти в байтах (как и следовало ожидать).Вот сравнение разных методов - самое
sys.getsizeof(df)
простое.В данном примере
df
это фрейм данных с 814 строками, 11 столбцами (2 интервала, 9 объектов) - считывается из шейп-файла 427 КБ.sys.getsizeof (DF)
df.memory_usage ()
df.info ()
Печатает информацию о фрейме данных в стандартный вывод. Технически это кибибайты (KiB), а не килобайты - как сказано в строке документации: «Использование памяти показано в единицах измерения, удобочитаемых человеком (представление base-2)». Таким образом, чтобы получить байты, нужно умножить на 1024, например 451,6 КиБ = 462 438 байтов.
источник
g
приведенный выше код?df.info(memory_usage="deep")
, она возвращает «392,6 МБ», в то время какsys.getsizeof(df)
иdf.memory_usage(index=True, deep=True).sum()
как возвращение примерно «411718016» (~ 411MB). Не могли бы вы объяснить, почему 3 результата не совпадают? спасибоdf.memory_usage(deep=True).sum()
возвращает почти то же самое, что иdf.memory_usage(index=True, deep=True).sum()
. в моем случаеindex
не занимает много памяти. Интересно, что я обнаружил, что411718016/1024/1024 = 392.6
поэтомуdf.info(memory_usage="deep")
можно использовать2^10
для преобразования байта в МБ , что меня смущает. В любом случае спасибо за вашу помощь: D.df.info
возвращает мебибайты (2 ^ 10), а не мегабайты (10 ^ 6) - поправим ответ.Я подумал, что внесу еще несколько данных в обсуждение.
Я провел серию тестов по этому вопросу.
Используя
resource
пакет python , я получил использование памяти моим процессом.И, записав csv в
StringIO
буфер, я мог легко измерить его размер в байтах.Я провел два эксперимента, в каждом из которых было создано 20 фреймов данных увеличивающегося размера от 10 000 до 1 000 000 строк. У обоих по 10 столбцов.
В первом эксперименте я использовал в своем наборе данных только числа с плавающей запятой.
Таким образом объем памяти увеличился по сравнению с файлом CSV в зависимости от количества строк. (Размер в мегабайтах)
Во втором эксперименте у меня был тот же подход, но данные в наборе данных состояли только из коротких строк.
Кажется, что соотношение размера csv и размера фрейма данных может сильно различаться, но размер в памяти всегда будет больше в 2-3 раза (для размеров фрейма в этом эксперименте)
Я хотел бы дополнить этот ответ дополнительными экспериментами, прокомментируйте, если вы хотите, чтобы я попробовал что-то особенное.
источник
Вы должны сделать это в обратном порядке.
Технически память об этом (включая индексы)
Итак, 168 МБ в памяти с файлом 400 МБ, 1 млн строк из 20 столбцов с плавающей запятой.
НАМНОГО компактнее при записи в виде двоичного файла HDF5
Данные были случайными, поэтому сжатие не слишком помогает
источник
read_csv
?iotop
лайкtop
/htop
для просмотра (в реальном времени) производительности ввода-вывода.nbytes
будет сильно недооценено, если у вас есть, например, строки в фрейме данных.Если вы знаете
dtype
s вашего массива, вы можете напрямую вычислить количество байтов, которое потребуется для хранения ваших данных + некоторые для самих объектов Python. Полезный атрибутnumpy
массивов - этоnbytes
. Вы можете получить количество байтов из массивов в пандахDataFrame
, выполнивobject
Массивы dtype хранят 8 байтов на объект (массивы dtype объектов хранят указатель на непрозрачный объектPyObject
), поэтому, если у вас есть строки в вашем csv, вам нужно принять во внимание, чтоread_csv
превратит их вobject
массивы dtype и соответствующим образом скорректирует ваши вычисления.РЕДАКТИРОВАТЬ:
См.
numpy
Страницу скалярных типов для получения дополнительных сведений оobject
dtype
. Поскольку сохраняется только ссылка, необходимо также учитывать размер объекта в массиве. Как говорится на этой странице, массивы объектов чем-то похожи наlist
объекты Python .источник
Да, есть. Pandas будет хранить ваши данные в двумерных
ndarray
структурах numpy, группируя их по типам.ndarray
в основном представляет собой необработанный массив данных C с небольшим заголовком. Таким образом, вы можете оценить его размер, просто умножив размер, которыйdtype
он содержит, на размеры массива.Например: если у вас есть 1000 строк с 2
np.int32
и 5np.float64
столбцами, ваш DataFrame будет иметь одинnp.int32
массив 2x1000 и одинnp.float64
массив 5x1000, который:4 байта * 2 * 1000 + 8 байтов * 5 * 1000 = 48000 байтов
источник
DataFrame
?pandas
имеет очень эффективную реализациюread_table
в Cython (это намного лучше, чем loadtxt numpy), поэтому я предполагаю, что он анализирует и сохраняет данные непосредственно вndarray
.Я считаю, что это дает размер в памяти любого объекта в python. Необходимо проверить внутренности на предмет pandas и numpy
источник