Как исправить в Pandas: SettingWithCopyWarning


Одно предупреждение, с которым вы можете столкнуться при использовании pandas:

SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.

Это предупреждение появляется, когда pandas сталкивается с чем-то, что называется цепным назначением — сочетанием цепочки и назначения за один шаг.

Важно отметить, что это просто предупреждение , а не ошибка. Ваш код по-прежнему будет выполняться, но результаты могут не всегда соответствовать вашим ожиданиям.

Самый простой способ подавить это предупреждение — использовать следующий фрагмент кода:

pd.options.mode.chained_assignment = None

В следующем примере показано, как устранить это предупреждение на практике.

Как воспроизвести предупреждение

Предположим, мы создаем следующие Pandas DataFrame:

import pandas as pd

#create DataFrame
df = pd.DataFrame({'A': [25, 12, 15, 14, 19, 23, 25, 29],
 'B': [5, 7, 7, 9, 12, 9, 9, 4],
 'C': [11, 8, 10, 6, 6, 5, 9, 12]})

#view DataFrame
df

 A B C
0 25 5 11
1 12 7 8
2 15 7 10
3 14 9 6
4 19 12 6
5 23 9 5
6 25 9 9
7 29 4 12

Теперь предположим, что мы создаем новый DataFrame, который содержит только столбец «A» из исходного DataFrame, и мы делим каждое значение в столбце «A» на 2:

#define new DataFrame
df2 = df[['A']]

#divide all values in column 'A' by 2
df2['A'] = df['A'] / 2

/srv/conda/envs/notebook/lib/python3.7/site-packages/ipykernel_launcher.py:2:
SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

Мы получаем сообщение SettingWithCopyWarning , потому что мы устанавливаем новые значения для столбца «A» в «срезе» исходного фрейма данных.

Однако, если мы посмотрим на созданный нами новый DataFrame, то увидим, что каждое значение было успешно разделено на 2:

#view new DataFrame
df2

 A
0 12.5
1 6.0
2 7.5
3 7.0
4 9.5
5 11.5
6 12.5
7 14.5

Несмотря на то, что мы получили предупреждающее сообщение, Pandas все же сделали то, что мы ожидали.

Как избежать предупреждения

Чтобы избежать предупреждения, рекомендуется использовать синтаксис .loc[индексатор строк, индексатор столбцов] следующим образом:

#define new DataFrame
df2 = df.loc[:, ['A']]

#divide each value in column 'A' by 2
df2['A'] = df['A'] / 2

#view result
df2

 A
0 12.5
1 6.0
2 7.5
3 7.0
4 9.5
5 11.5
6 12.5
7 14.5

Новый DataFrame содержит все значения из столбца «A» в исходном DataFrame, разделенные на два, и предупреждающее сообщение не появляется.

Если мы хотим предотвратить появление предупреждающего сообщения, мы можем использовать следующий фрагмент кода:

#prevent SettingWithCopyWarning message from appearing
pd.options.mode.chained_assignment = None

За подробным объяснением того, почему следует избегать цепного присваивания, обратитесь к онлайн-документации pandas .

Дополнительные ресурсы

Как исправить: нет модуля с именем pandas
Как исправить: нет модуля с именем numpy
Как исправить: столбцы перекрываются, но суффикс не указан

Замечательно! Вы успешно подписались.
Добро пожаловать обратно! Вы успешно вошли
Вы успешно подписались на кодкамп.
Срок действия вашей ссылки истек.
Ура! Проверьте свою электронную почту на наличие волшебной ссылки для входа.
Успех! Ваша платежная информация обновлена.
Ваша платежная информация не была обновлена.