2014-06-05 74 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