Короткий ответ
SettingWithCopyWarning сигнализирует, что изменение значения происходит на объекте, про который pandas не может гарантировать, является ли он копией или видом исходных данных; правильный способ — выполнять фильтрацию и присвоение в одной операции через .loc.
Как это работает подробнее
при цепочечной индексации вида df[mask]['col'] = value сначала создаётся промежуточный объект (результат df[mask]), а затем в него пытаются записать значение; pandas не гарантирует, что этот промежуточный объект — view на оригинал или отдельная копия, из-за чего присвоение может как сработать, так и не сработать, и выдаётся предупреждение.
Пример кода
question-123.py
import pandas as pd
df = pd.DataFrame({'a': [1, 2, 3], 'b': [10, 20, 30]})
df.loc[df['a'] > 1, 'b'] = 0
print(df)Что использовать на практике
- Практика. безопасный способ — df.loc[mask, 'col'] = value, выполняющий фильтрацию и присвоение атомарно за один вызов; если результат фильтрации предполагается использовать как самостоятельный объект для дальнейших изменений, его стоит явно скопировать через .copy().
- Проверка. после операции строки с a>1 (вторая и третья) должны получить b=0, а строка с a=1 останется с b=10, без предупреждений в выводе.
Подводные камни
- Частая ошибка. игнорируют предупреждение и продолжают работу, не проверив, действительно ли изменения применились к нужному объекту; "решают" проблему добавлением pd.options.mode.chained_assignment = None, что просто скрывает предупреждение, а не устраняет источник неоднозначности.