Copy, view и SettingWithCopyWarning в pandas

Почему важно явно использовать copy и стараться избегать связанных операций при изменении в выборках датасета.

Разберемся сначала с понятиями ‘view‘ (представление) и ‘copy‘ (копия).

view – срез, сформированный из оригинального объекта, а copy (копия) – новый объект. Когда мы меняем представления (view), мы меняем исходный объект, а изменения копии меняют новый объект.

Важным моментом для работы с pandas является понимание работы связанных (chained) операций и что получается в результате.
Допустим, имеем

В результате выполнения, мы не получим изменения в оригинальном датафрейме, а получим изменения в копии и скорее всего предупреждение SettingWithCopyWarning (это зависит от ваших настроек mode.chained_assignment).

Что бы понять, почему мы получаем копию, стоит вспомнить, что фактически здесь выполняется два действия:

1) получение (get) операция, где в результате получаем датафрейм, удовлетворяющий условию df[df['A'] > 1] – все строки, где значение A больше 1

2) операция установки (set), которая происходит с новым датафреймом

Такой же результат будет и при использовании loc.

Для замены в оригинальном датафрейме следует воспользоваться полной записью loc (об этом и сообщает предупрждение SettingWithCopyWarning), т.е. присваиванием в одну операцию.

Но на этом приключения с копией и представлением не заканчиваются, так как имеет место еще и скрытые связанные операции (Hidden Chaining).

Получим новый датафрейм на база оригинального

и получим SettingWithCopyWarning

А почему? Потому что связанная операция может выполняться как в одной строке, так и в двух! И между этими строками может быть какой-то код.

Результат выполнения в этом случае будет ожидаем:

Но для pandas мы все так же пытались изменить оригинальный датасет, и случайно сделали копию, хотя это не так.

Во избежания этих ситуаций стоит явно использовать метод copy.

И никаких SettingWithCopyWarning предупреждений!

Для работы над view, стоит избегать связанных операций и использовать присваивание в одну операцию с использованием loc.

Для работы с SettingWithCopyWarning можно настроить варианты работы через опцию mode.chained_assignment:
‘raise’ — вызвать исключение вместо предупреждения
‘warn’ — выдать предупреждение (по умолчанию)
None — полностью отключить предупреждение