Pandas:子索引数据帧:副本与视图
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 
原文地址: http://stackoverflow.com/questions/17960511/
Warning: these are provided under cc-by-sa 4.0 license.  You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Pandas: Subindexing dataframes: Copies vs views
提问by Amelio Vazquez-Reina
Say I have a dataframe
说我有一个数据框
import pandas as pd
import numpy as np
foo = pd.DataFrame(np.random.random((10,5)))
and I create another dataframe from a subset of my data:
我从我的数据子集创建另一个数据框:
bar = foo.iloc[3:5,1:4]
does barhold a copy of those elements from foo? Is there any way to create a viewof that data instead? If so, what would happen if I try to modify data in this view? Does Pandas provide any sort of copy-on-writemechanism?
是否bar持有这些元素的副本foo?有什么方法可以创建view该数据?如果是这样,如果我尝试修改此视图中的数据会发生什么?Pandas 是否提供任何类型的写时复制机制?
回答by davidshinn
Your answer lies in the pandas docs: returning-a-view-versus-a-copy.
您的答案在 pandas 文档中:return-a-view-versus-a-copy。
Whenever an array of labels or a boolean vector are involved in the indexing operation, the result will be a copy. With single label / scalar indexing and slicing, e.g. df.ix[3:6] or df.ix[:, 'A'], a view will be returned.
每当索引操作中涉及标签数组或布尔向量时,结果将是一个副本。使用单标签/标量索引和切片,例如 df.ix[3:6] 或 df.ix[:, 'A'],将返回一个视图。
In your example, baris a viewof slices of foo.  If you wanted a copy, you could have used the copymethod.  Modifying baralso modifies foo.  pandas does not appear to have a copy-on-write mechanism.
在你的榜样,bar是一个视图的切片foo。如果你想要一个副本,你可以使用这个copy方法。修改bar也会修改foo. pandas 似乎没有写时复制机制。
See my code example below to illustrate:
请参阅下面的代码示例来说明:
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

