了解pandas数据帧索引

K.-*_*Aye 13 python dataframe pandas

摘要:这不起作用:

df[df.key==1]['D'] = 1
Run Code Online (Sandbox Code Playgroud)

但这样做:

df.D[df.key==1] = 1
Run Code Online (Sandbox Code Playgroud)

为什么?

再生产:

In [1]: import pandas as pd

In [2]: from numpy.random import randn

In [4]: df = pd.DataFrame(randn(6,3),columns=list('ABC'))

In [5]: df
Out[5]: 
          A         B         C
0  1.438161 -0.210454 -1.983704
1 -0.283780 -0.371773  0.017580
2  0.552564 -0.610548  0.257276
3  1.931332  0.649179 -1.349062
4  1.656010 -1.373263  1.333079
5  0.944862 -0.657849  1.526811

In [6]: df['D']=0.0

In [7]: df['key']=3*[1]+3*[2]

In [8]: df
Out[8]: 
          A         B         C  D  key
0  1.438161 -0.210454 -1.983704  0    1
1 -0.283780 -0.371773  0.017580  0    1
2  0.552564 -0.610548  0.257276  0    1
3  1.931332  0.649179 -1.349062  0    2
4  1.656010 -1.373263  1.333079  0    2
5  0.944862 -0.657849  1.526811  0    2
Run Code Online (Sandbox Code Playgroud)

这不起作用:

In [9]: df[df.key==1]['D'] = 1

In [10]: df
Out[10]: 
          A         B         C  D  key
0  1.438161 -0.210454 -1.983704  0    1
1 -0.283780 -0.371773  0.017580  0    1
2  0.552564 -0.610548  0.257276  0    1
3  1.931332  0.649179 -1.349062  0    2
4  1.656010 -1.373263  1.333079  0    2
5  0.944862 -0.657849  1.526811  0    2
Run Code Online (Sandbox Code Playgroud)

但这样做:

In [11]: df.D[df.key==1] = 3.4

In [12]: df
Out[12]: 
          A         B         C    D  key
0  1.438161 -0.210454 -1.983704  3.4    1
1 -0.283780 -0.371773  0.017580  3.4    1
2  0.552564 -0.610548  0.257276  3.4    1
3  1.931332  0.649179 -1.349062  0.0    2
4  1.656010 -1.373263  1.333079  0.0    2
5  0.944862 -0.657849  1.526811  0.0    2
Run Code Online (Sandbox Code Playgroud)

链接到笔记本

我的问题是:为什么只有第二种方式有效?我似乎无法看到选择/索引逻辑的差异?

版本是0.10.0

编辑:这不应该这样做了.从0.11开始.loc,请看这里:http://pandas.pydata.org/pandas-docs/stable/indexing.html

Tho*_*anz 17

熊猫文档说:

返回视图与副本

关于何时返回数据视图的规则完全取决于NumPy.每当索引操作中涉及标签数组或布尔向量时,结果将是副本.使用单标签/标量索引和切片,例如df.ix [3:6]或df.ix [:,'A'],将返回视图.

df[df.key==1]['D']你首先做布尔切片(导致Dataframe的副本),然后你选择一个列['D'].

df.D[df.key==1] = 3.4,您首先选择一列,然后对生成的系列执行布尔切片.

这似乎有所不同,虽然我必须承认它有点违反直觉.

编辑:差异由Dougal确定,请参阅他的评论:对于版本1,复制是在__getitem__调用布尔切片的方法时生成的.对于版本2,只__setitem__访问该方法 - 因此不返回副本而只是分配.

  • @ K.-MichaelAye在第一种方式中,首先使用`__getitem__`构造一个副本,然后在该副本上调用`__setitem__`,然后立即进行垃圾回收.在第二种方式中,您使用`__getitem__`构造一个视图,然后在视图上调用`__setitem__`. (4认同)