Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 理解数据帧索引_Python_Pandas_Dataframe - Fatal编程技术网

Python 理解数据帧索引

Python 理解数据帧索引,python,pandas,dataframe,Python,Pandas,Dataframe,总结: 这不起作用: df[df.key==1]['D'] = 1 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

总结: 这不起作用:

df[df.key==1]['D'] = 1
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
但这确实:

df.D[df.key==1] = 1
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
为什么?

复制:

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
这不起作用:

df[df.key==1]['D'] = 1
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
但这确实:

df.D[df.key==1] = 1
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
。请看这里:


我很确定,您的第一种方法是返回一个副本,而不是一个视图,因此分配给它不会改变原始数据。但我不知道为什么会发生这种情况

它似乎与您选择行和列的顺序有关,而与获取列的语法无关。这两种方法都有效:

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论坛上发布:

熊猫文档中说:

返回视图而不是副本

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

df[df.key==1]['D']
中,首先执行布尔切片(生成数据帧的副本),然后选择列['D']

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

虽然我必须承认这有点违反直觉,但这似乎起了作用


编辑:差异由Dougal确定,请参见他的评论:在版本1中,当布尔切片调用
\uuuu getitem\uuuu
方法时,复制。对于版本2,只访问
\uuu setitem\uuuu
方法-因此不返回副本,而只是分配。

这也是我最初的想法,但肯定还有其他事情发生
df[df.key==1]=1000实际上会将1000分配给切片中的所有值,因此它不能是副本。我猜setattr或setitem方法中发生了一些神奇的事情。但是当我对结果序列进行布尔切片时,这应该也是一个副本,不是吗?那么为什么作业是这样的呢?看看上面道格拉斯的评论。对于版本1,在调用getitem方法进行布尔切片时进行复制。对于版本2,只访问setitem方法-因此不返回副本,而只是赋值。@K.-MichaelAye在第一种方式中,您首先使用
\uuuuu getitem\uuuuuuuuu
构造一个副本,然后对该副本调用
\uuuuuu setitem\uuuuuuuuu
,然后立即对其进行垃圾回收。在第二种方法中,您使用
\uuuu getitem\uuuuuuuuuuu
构造一个视图,然后在视图上调用
\uuuuuuuu setitem\uuuuuuuuuuu
df[df.key==1]
实际上返回一个副本(正如Thorsten的回答所指出的)。
df[df.key==1]=0
修改原文的原因是,尽管语法有点误导,但实际上根本不是做同样的事情;非赋值版本调用
\uuuuu getitem\uuuuuu
和赋值版本
\uuuuuuuu setitem\uuuuuu
。这就像如果我们有
l=[0,1,2]
,那么
l[1]
返回int 1,但
l[1]=5
修改了原始值。正如答案中所说,这似乎是一个关键问题:看看是否存在类似的问题。我不确定这是否是一个视图与副本的问题。我现在明白了,视图与副本的区别很明显(实际上很简单)。第一个方法只提供垃圾收集的副本。第二个方法提供了一个视图,因此设置是在原始数据帧上完成的。(见下文道格尔的评论)