2014-06-05 133 views
0

未定義列如果你潛在缺陷:使用ILOC

>>> df = pd.DataFrame(np.arange(0,9), columns=['count']) 
>>> df.iloc[0:5]['group'] = 'a' 
>>> df 
Out[346]: 
    count 
0  0 
1  1 
2  2 
3  3 
4  4 
5  5 
6  6 
7  7 
8  8 

沒有價值將被設置設定值。但是,如果你第一次做

>>> df['group'] = 'b' 
>>> df.iloc[0:5]['group'] = 'a' 
>>> df 
    Out[353]: 
    count group 
0  0  a 
1  1  a 
2  2  a 
3  3  a 
4  4  a 
5  5  b 
6  6  b 
7  7  b 
8  8  b 

對我來說,這是意想不到的行爲。無論我是否使用iloc來篩選某些列,我都希望這能起作用。但是,如果這不起作用,至少我會期待一個錯誤/警告。我只希望沒有值被設置,並且沒有任何警告,當我使用索引設置一些值並且索引實際上不存在於左側時。

我在

>>> pd.__version__ 
Out[355]: '0.14.0rc1-51-gccd593f' 
+0

不知道這是否是一個錯誤或沒有,但'df.loc [0:5,「羣」] =「A」 '有和沒有創建初始列 – EdChum

+0

您是鏈索引,請參閱:http://pandas-docs.github.io/pandas-docs-travis/indexing。html#indexing-view-versus-copy;使用ix/loc – Jeff

+0

我應該不會收到「SettingWithCopy」錯誤嗎? – FooBar

回答

0

不,這不是一個錯誤:當你打電話

df.iloc[0:5]['group'] 

會發生什麼 「引擎蓋下」 實際上是兩個調用:

m = df.iloc[0:5] 
m['group'] = 'a' 

,正如你所見,df根本沒有改變。但是,這樣做:

df['group'] = 'b' 

你真正改變df,如果你會print df在這一點上,你會得到另一列滿b S:當你繼續

count group 
0  0  b 
1  1  b 
2  2  b 
3  3  b 
4  4  b 
5  5  b 
6  6  b 
7  7  b 
8  8  b 

所以而這樣做的:

df.iloc[0:5]['group'] = 'a' 

你改變你剛剛加入到df列。

傑夫在上面的評論中提到,根據docs

有時,當你切開一個數組,你只會得到一個觀點回來, 這意味着你可以將它設置沒有問題。然而,如果以特定的方式

此外切片甚至單個dtyped 陣列可生成副本:


enter image description here

這意味着大熊貓的設計者允許不同的行爲(返回一個視圖與返回一個副本),可能是爲了實現性能,爲了不會陷入這種意想不到的行爲,他們會在文檔中警告您並提供了「正確」的使用方式,即df.loc[0:5,'group'] = 'a'

總之,這是不是一個錯誤 - 它的「設計」

+0

在第二種情況下,再次,最後的命令應該被分成兩個命令,它會做'm ['group'] ='a'' - 用你的話說,'df'根本不會改變。如果你的觀點與Jeff相同,那麼我將在一個副本上設置值:爲什麼它仍然在第二個示例中設置值,但不是第一個示例中的值?此外,爲什麼我沒有得到'settingWithCopy'警告? – FooBar

+0

@FooBar看到更新的答案。 – alfasin