Tujuan utama adalah untuk menghindari pengindeksan berantai dan menghilangkan SettingWithCopyWarning
.
Di sini pengindeksan berantai adalah sesuatu seperti dfc['A'][0] = 111
Dokumen itu mengatakan pengindeksan berantai harus dihindari dalam Mengembalikan tampilan versus salinan . Berikut adalah contoh yang sedikit dimodifikasi dari dokumen itu:
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
Di sini aColumn
adalah tampilan dan bukan salinan dari DataFrame asli, jadi memodifikasi aColumn
akan menyebabkan yang asli dfc
juga dimodifikasi. Selanjutnya, jika kita mengindeks baris pertama:
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
Kali ini zero_row
adalah salinan, jadi yang asli dfc
tidak diubah.
Dari dua contoh di atas, kami melihat ambigu apakah Anda ingin mengubah DataFrame asli atau tidak. Ini sangat berbahaya jika Anda menulis sesuatu seperti berikut:
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
Kali ini tidak berhasil sama sekali. Di sini kami ingin mengubah dfc
, tetapi kami benar-benar mengubah nilai menengah dfc.loc[0]
yang merupakan salinan dan segera dibuang. Sangat sulit untuk memprediksi apakah nilai antara suka dfc.loc[0]
atau tidak dfc['A']
adalah tampilan atau salinan, jadi tidak dijamin apakah DataFrame asli akan diperbarui atau tidak. Itu sebabnya pengindeksan berantai harus dihindari, dan panda menghasilkan SettingWithCopyWarning
pembaruan pengindeksan berantai seperti ini.
Sekarang adalah penggunaan .copy()
. Untuk menghilangkan peringatan, buat salinan untuk mengekspresikan niat Anda secara eksplisit:
In [12]: zero_row_copy = dfc.loc[0].copy()
In [13]: zero_row_copy['A'] = 444 # This time no warning
Karena Anda memodifikasi salinan, Anda tahu yang asli dfc
tidak akan pernah berubah dan Anda tidak mengharapkannya untuk berubah. Harapan Anda cocok dengan perilaku, lalu SettingWithCopyWarning
menghilang.
Catatan, Jika Anda ingin memodifikasi DataFrame asli, dokumen menyarankan Anda menggunakan loc
:
In [14]: dfc.loc[0,'A'] = 555
In [15]: dfc
Out[15]:
A B
0 555 1
1 bbb 2
2 ccc 3