Таблицы в pandas хранятся как в колоночной БД, в виде серий или Series
. Поэтому построчные операции даются панде не так хорошо, как операции с колонками. Забегая вперёд, можно сказать, что это обёртка над numpy-массивами.
Блоки оптимизированы для хранения значений, имеющихся в ячейках таблицы объекта DataFrame
. За хранение сведений о соответствии между индексами строк и столбцов набора данных и того, что хранится в блоках однотипных данных, отвечает класс BlockManager
. Он играет роль API, который предоставляет доступ к базовым данным. Когда мы читаем, редактируем или удаляем значения, DataFrame
общается сBlockManager
для преобразования наших запросов в вызовы функций и методов.
Каждый тип данных имеет специализированный класс в модуле pandas.core.internals
. Например, pandas использует класс ObjectBlock
для представления блоков, содержащих строковые столбцы, и класс FloatBlock
для представления блоков, содержащих столбцы, хранящие числа с плавающей точкой. Для блоков, представляющих числовые значения,
выглядящие как целые числа или числа с плавающей точкой, pandas комбинирует столбцы и хранит их в виде структуры данных ndarray
. Эта структура данных построена на основе массива C, значения хранятся в непрерывном блоке памяти. Благодаря такой схеме хранения данных доступ к фрагментам данных осуществляется очень быстро.
Прикольный момент заключается в том, что уже тут можно ускориться просто установив расширенный пулл зависимостей, которые любит pandas, например, pyArrow
. А ещё можно ускориться, заменив object-тип на, например, доступный из коробки Categorical.
Кстати, Join в pandas работает не по колоночным индексам, а по общему индексу, что тоже неплохо было бы упомянуть. Кроме того, имплементации индексов и операции переиндексирования работают очень и очень долго, потому что реализованы не очень-то прямо: вот ишью на гите.
Ускорение можно поделить на несколько видов:
ffill()
.