14

摘要:这不起作用:

df[df.key==1]['D'] = 1

但这确实:

df.D[df.key==1] = 1

为什么?

再生产:

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

这不起作用:

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

但这确实:

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

链接到笔记本

我的问题是:

为什么只有第二种方式有效?我似乎看不出选择/索引逻辑有什么不同。

版本是 0.10.0

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

4

2 回答 2

17

熊猫文档说:

返回视图与副本

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

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

df.D[df.key==1] = 3.4中,您首先选择一列,然后对结果Series进行布尔切片。

这似乎有所作为,尽管我必须承认这有点违反直觉。

编辑:Dougal 发现了差异,请参阅他的评论:在版本 1 中,复制是在__getitem__调用布尔切片的方法时制作的。对于版本 2,仅__setitem__访问方法 - 因此不返回副本,而只是分配。

于 2013-01-07T09:32:27.723 回答
4

我很确定您的第一种方法是返回副本,而不是视图,因此分配给它不会更改原始数据。我不确定为什么会这样。

它似乎与您选择行和列的顺序有关,而不是与获取列的语法有关。这些都有效:

df.D[df.key == 1] = 1
df['D'][df.key == 1] = 1

这些都不起作用:

df[df.key == 1]['D'] = 1
df[df.key == 1].D = 1

从这个证据来看,我会假设切片df[df.key == 1]正在返回一个副本。但这种情况并非如此!df[df.key == 1] = 0实际上会改变原始数据,就好像它是一个视图一样。

所以,我不确定。我的感觉是这种行为随着熊猫的版本而改变。我似乎记得 df.D 用于返回副本而 df['D'] 用于返回视图,但这似乎不再是真的(熊猫 0.10.0)。

如果您想要更完整的答案,您应该在 pystatsmodels 论坛发帖: https ://groups.google.com/forum/?fromgroups#!forum/pystatsmodels

于 2013-01-07T09:27:17.380 回答