Копирование при записи#

Copy on Write — это механизм для упрощения API индексирования и повышения производительности за счёт избегания копирования, когда это возможно. CoW означает, что любой DataFrame или Series, полученный из другого любым способом, всегда ведёт себя как копия. Объяснение того, как эффективно использовать Copy on Write, можно найти здесь.

Отслеживание ссылок#

Чтобы иметь возможность определить, нужно ли делать копию при записи в DataFrame, мы должны знать, используются ли значения совместно с другим DataFrame. pandas отслеживает все Blocks которые делят значения с другим блоком внутри, чтобы иметь возможность определить, когда нужно вызвать копирование. Механизм отслеживания ссылок реализован на уровне Block.

Мы используем пользовательский объект отслеживания ссылок, BlockValuesRefs, который отслеживает каждый блок, чьи значения совместно используют память друг с другом. Ссылка удерживается через слабую ссылку. Каждая пара блоков, которые совместно используют память, должна указывать на один и тот же BlockValuesRefs объект. Если один блок выходит из области видимости, ссылка на этот блок умирает. Как следствие, объект отслеживания ссылок всегда знает, сколько блоков активно и разделяет память.

Всякий раз, когда DataFrame или Series объект делит данные с другим объектом, требуется, чтобы каждый из этих объектов имел свои собственные объекты BlockManager и Block. Таким образом, другими словами, один экземпляр Block (который удерживается DataFrame, не обязательно для промежуточных объектов) всегда должен использоваться уникально только для одного объекта DataFrame/Series. Например, когда вы хотите использовать тот же Block для другого объекта, вы можете создать поверхностную копию экземпляра Block с block.copy(deep=False) (что создаст новый экземпляр Block с теми же базовыми значениями и правильно настроит ссылки).

Мы можем спросить объект отслеживания ссылок, есть ли другой активный блок, который делится данными с нами, перед записью в значения. Мы можем вызвать копирование перед записью, если действительно есть другой активный блок.