Birincil amaç zincirleme indekslemeden kaçınmak ve SettingWithCopyWarning
.
Burada zincirleme endeksleme dfc['A'][0] = 111
Bir kopyaya karşı görünüm döndürülmesinde belirtilen zincirleme indekslemeden kaçınılmalıdır . İşte bu belgeden biraz değiştirilmiş bir örnek:
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
Burada, aColumn
orijinal DataFrame'in bir kopyası değil, bir görünümdür, bu nedenle değiştirilmesi aColumn
orijinalin dfc
de değiştirilmesine neden olur . Ardından, önce satırı dizine eklersek:
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
Bu sefer zero_row
bir kopya, yani orijinaldfc
değiştirilmez.
Yukarıdaki bu iki örnekten, orijinal DataFrame'i değiştirmek isteyip istemediğinizi belirsiz görüyoruz. Aşağıdaki gibi bir şey yazarsanız bu özellikle tehlikelidir:
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
Bu sefer hiç işe yaramadı. Burada değiştirmek istedik dfc
, ancak aslında dfc.loc[0]
bir kopya olan ve hemen atılan bir ara değeri değiştirdik . Sanki ara değer olup olmadığını tahmin etmek çok zordur dfc.loc[0]
ya dfc['A']
da orijinal DataFrame güncellenecektir olsun veya olmasın garanti değil bu yüzden, bir görünüm veya bir kopyasıdır. Bu yüzden zincirleme indekslemeden kaçınılmalı ve pandalarSettingWithCopyWarning
bu tür zincirleme indeksleme güncellemesi için oluşturur.
Şimdi kullanımı .copy()
. Uyarıyı ortadan kaldırmak için niyetinizi açıkça ifade etmek üzere bir kopyasını alın:
In [12]: zero_row_copy = dfc.loc[0].copy()
In [13]: zero_row_copy['A'] = 444 # This time no warning
Bir kopyayı değiştirdiğiniz için, orijinalin dfc
asla değişmeyeceğini ve değiştirilmesini beklemediğinizi biliyorsunuz. Beklentiniz davranışla eşleşir, ardındanSettingWithCopyWarning
kaybolur.
Not: Orijinal DataFrame'i değiştirmek istiyorsanız, belge şunları kullanmanızı önerir loc
:
In [14]: dfc.loc[0,'A'] = 555
In [15]: dfc
Out[15]:
A B
0 555 1
1 bbb 2
2 ccc 3