Copy-on-Write и SettingWithCopyWarning
Вопрос
Объясните, откуда бралось SettingWithCopyWarning и что изменил Copy-on-Write в pandas 3.0.
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Раньше срез мог быть и view, и копией, и pandas не знал наверняка
Цепочное присваивание могло не изменить исходную таблицу, отсюда предупреждение
CoW: любой производный объект ведёт себя как копия, копирование ленивое
Цепочное присваивание в 3.0 никогда не работает, правильно через `loc`
Меньше копий в цепочках методов: выигрыш по памяти
Код, который менял df через колонку или срез, при миграции ломается
Что могут спросить следом
- Как найти такие места при переходе на 3.0?
- Что выведет
col = df["a"]; col[0] = 1?
Разбор
В старом pandas результат индексации мог оказаться представлением исходных данных или копией в зависимости от типа операции и раскладки памяти. Поэтому df[mask]["b"] = 0 иногда менял таблицу, а иногда нет, и pandas честно предупреждал SettingWithCopyWarning. Copy-on-Write убирает неоднозначность: любой объект, полученный из DataFrame, ведёт себя как независимая копия, а реальное копирование откладывается до первой записи. Следствия: цепочное присваивание никогда не меняет исходник, писать нужно одной операцией df.loc[mask, "b"] = 0. Изменение колонки, вынутой в переменную, тоже не трогает таблицу. Плюс в производительности: rename, reset_index и другие методы в цепочке больше не копируют данные. При переходе на 3.0 ищу места, где код рассчитывал на изменение через срез, в 2.2 их подсвечивает режим pd.options.mode.copy_on_write = "warn".
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Термины по теме
Ещё по теме «Производительность и память»
- Чем заменить apply(axis=1)
- Когда помогает тип category
- Цепочное присваивание в pandas 3.0
- Обнулить тестовые заказы через loc
- Скидка по категории через map
- Категории сумм через np.select
- Ужать DataFrame: category и downcast
- category теряется при concat