Pandas: 数据帧的子索引:副本 vs 视图

31

假设我有一个数据框(DataFrame)

import pandas as pd
import numpy as np
foo = pd.DataFrame(np.random.random((10,5)))

我从数据的子集中创建了另一个数据帧:

bar = foo.iloc[3:5,1:4]

bar是否保存了从foo中复制的那些元素?有没有办法创建一个该数据的view?如果有,那么在这个view中尝试修改数据会发生什么?Pandas提供任何形式的写时复制机制吗?


当我执行bar.loc[:, ['a', 'b']]时,它返回一个副本,但是当我执行bar.loc[:, 'a']时,它返回一个视图? - Lisa
1个回答

41

您可以在pandas文档中找到答案:返回视图与副本

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

在您的示例中,barfoo切片的视图。如果您想要一个副本,可以使用copy方法。修改bar也会修改foo。pandas似乎没有写时复制机制。

请参见下面的代码示例:

In [1]: import pandas as pd
   ...: import numpy as np
   ...: foo = pd.DataFrame(np.random.random((10,5)))
   ...: 

In [2]: pd.__version__
Out[2]: '0.12.0.dev-35312e4'

In [3]: np.__version__
Out[3]: '1.7.1'

In [4]: # DataFrame has copy method
   ...: foo_copy = foo.copy()

In [5]: bar = foo.iloc[3:5,1:4]

In [6]: bar == foo.iloc[3:5,1:4] == foo_copy.iloc[3:5,1:4]
Out[6]: 
      1     2     3
3  True  True  True
4  True  True  True

In [7]: # Changing the view
   ...: bar.ix[3,1] = 5

In [8]: # View and DataFrame still equal
   ...: bar == foo.iloc[3:5,1:4]
Out[8]: 
      1     2     3
3  True  True  True
4  True  True  True

In [9]: # It is now different from a copy of original
   ...: bar == foo_copy.iloc[3:5,1:4]
Out[9]: 
       1     2     3
3  False  True  True
4   True  True  True

1
当我执行bar.loc[:, ['a', 'b']]时,它返回一个副本,但是当我执行bar.loc[:, 'a']时,它返回一个视图? - Lisa
2
bar.loc[:, 'a'] 的作用类似于切片,返回一个视图,而 bar.loc[:, ['a', 'b']] 使用列表索引,返回一个副本。请注意,bar.loc[:, ['a']] 也会返回一个副本。 - davidshinn
1
bar['a']是视图还是副本? - Lisa
1
@davidshinn,你提供的文档中还有这个突出显示的引用吗?我找不到它! - Pietro Marchesi
3
原始回复已经进行了修订(引用文本在版本0.13中):http://pandas.pydata.org/pandas-docs/version/0.13/indexing.html#indexing-view-versus-copy。 - davidshinn
1
顶部链接不再指向包含此信息的页面。 - johnDanger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接