Основна мета - уникнути ланцюгової індексації та усунути SettingWithCopyWarning
.
Тут ланцюгова індексація - щось подібне dfc['A'][0] = 111
У документі зазначено, що слід уникати ланцюгової індексації при поверненні подання проти копії . Ось трохи змінений приклад цього документа:
In [1]: import pandas as pd
In [2]: dfc = pd.DataFrame({'A':['aaa','bbb','ccc'],'B':[1,2,3]})
In [3]: dfc
Out[3]:
A B
0 aaa 1
1 bbb 2
2 ccc 3
In [4]: aColumn = dfc['A']
In [5]: aColumn[0] = 111
SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame
In [6]: dfc
Out[6]:
A B
0 111 1
1 bbb 2
2 ccc 3
Тут aColumn
представлений вид, а не копія оригіналу DataFrame, тому зміна aColumn
призведе до зміни оригіналу dfc
. Далі, якщо спочатку індексуємо рядок:
In [7]: zero_row = dfc.loc[0]
In [8]: zero_row['A'] = 222
SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame
In [9]: dfc
Out[9]:
A B
0 111 1
1 bbb 2
2 ccc 3
Цей час zero_row
є копією, тому оригінал dfc
не змінюється.
З цих двох прикладів, наведених вище, ми бачимо, що неоднозначно ви хочете змінити оригінальну DataFrame чи ні. Це особливо небезпечно, якщо ви пишете щось подібне:
In [10]: dfc.loc[0]['A'] = 333
SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame
In [11]: dfc
Out[11]:
A B
0 111 1
1 bbb 2
2 ccc 3
Цього разу це зовсім не спрацювало. Тут ми хотіли змінити dfc
, але ми фактично змінили проміжне значення, dfc.loc[0]
яке є копією і негайно відкидається. Це дуже важко передбачити , буде чи проміжне значення , як dfc.loc[0]
і dfc['A']
вид або копію, так що це не гарантовано , буде чи не буде оновлюватися оригінал DataFrame. Ось чому слід уникати ланцюгової індексації, а панди створюють SettingWithCopyWarning
для цього виду ланцюгового оновлення індексації.
Зараз це використання .copy()
. Щоб усунути попередження, зробіть копію, щоб виразно висловити свій намір:
In [12]: zero_row_copy = dfc.loc[0].copy()
In [13]: zero_row_copy['A'] = 444 # This time no warning
Оскільки ви dfc
змінюєте копію, ви знаєте, що оригінал ніколи не зміниться, і ви не очікуєте, що він зміниться. Ваше очікування відповідає поведінці, то SettingWithCopyWarning
зникає.
Примітка. Якщо ви хочете змінити оригінальний DataFrame, документ пропонує використовувати loc
:
In [14]: dfc.loc[0,'A'] = 555
In [15]: dfc
Out[15]:
A B
0 555 1
1 bbb 2
2 ccc 3