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

时间:2014-06-05 07:46:10

标签: 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['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'

1 个答案:

答案 0 :(得分: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

正如Jeff在上面的评论中提到的,根据 docs

  

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

此外:


enter image description here

这意味着pandas的设计者允许不同的行为(返回视图而不是返回副本),可能是为了达到性能,为了不陷入这种意外行为,他们在文档中警告你并提供“权利” “使用方式是df.loc[0:5,'group'] = 'a'

总而言之,这不是一个错误 - 它是“按设计”