Python 潜在错误:使用iloc设置未定义列的值

Python 潜在错误:使用iloc设置未定义列的值,python,pandas,Python,Pandas,如果你这样做 >>> 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 = 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'

不,这不是窃听器:当你打电话的时候

df.iloc[0:5]['group']
引擎盖下发生的实际上是两个呼叫:

m = df.iloc[0:5]
m['group'] = 'a'
正如您所看到的,df根本没有改变。但是,通过这样做:

df['group'] = 'b'
实际上您更改了df,如果此时打印df,您将得到另一列充满bs的内容:

因此,当您继续并执行以下操作时:

df.iloc[0:5]['group'] = 'a'
您正在更改刚刚添加到df的列

正如杰夫在上述评论中提到的,根据:

有时候,当你切片一个数组时,你只需要返回一个视图, 这意味着你可以设置它没有问题。但是,即使是一个数据类型 如果数组以特定方式切片,则它可以生成副本

进一步:

这意味着pandas的设计者允许返回视图和返回副本的不同行为,可能是为了实现性能,为了避免陷入这种意外行为,他们在文档中警告您,并提供了正确的使用方式,即df.loc[0:5,'group']='a'


总之,这不是一个bug-这是设计上的

不知道这是否是一个bug,但是df.loc[0:5,'group']='a'在创建和不创建初始列的情况下都有效。您是链索引,请参见此处:;使用ix/LOC我不应该得到一个SETTINGWITH copy error吗?@Jeff:而且,如果我只设置一个副本:如果我在设置值之前创建列,为什么它会起作用?第二个示例应该在整个过程中保持列值b,因为第二个命令再次使用iloc,并且只在副本上设置值;SettingWithCopy是一种启发式方法,它可能是一个bug,它没有显示警告。这是两个完全独立的python操作。在第二种情况下,最后一个命令应该被分成两个命令,它将执行m['group']='a'——用你的话来说,df根本没有改变。如果你和Jeff的观点相同,我在副本上设置值:为什么在第二个示例中它仍然设置值,而不是在第一个示例中?而且,为什么我不能得到一个复制警告设置?
df.iloc[0:5]['group'] = 'a'