2013-04-30 68 views
4

我怎样才能避免采取建立大熊猫数据帧时提供的字典中的副本?熊猫数据帧不复制

>>> a = np.arange(10) 
>>> b = np.arange(10.0) 
>>> df1 = pd.DataFrame(a) 
>>> a[0] = 100 
>>> df1 
    0 
0 100 
1 1 
2 2 
3 3 
4 4 
5 5 
6 6 
7 7 
8 8 
9 9 
>>> d = {'a':a, 'b':b} 
>>> df2 = pd.DataFrame(d) 
>>> a[1] = 200 
>>> d 
{'a': array([100, 200, 2, 3, 4, 5, 6, 7, 8, 9]), 'b': array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])} 
>>> df2 
    a b 
0 100 0 
1 1 1 
2 2 2 
3 3 3 
4 4 4 
5 5 5 
6 6 6 
7 7 7 
8 8 8 
9 9 9 

如果我只是从a创建数据框,那么在df中反映的变化(反之亦然)。

有没有提供一个字典时使这项工作的方法吗?

+2

I *完全*没有意识到它这样做。 – 2013-04-30 21:23:40

回答

3

有没有办法来“分享”的字典,并具有基于字典的变化框架更新。副本的说法是不相关的字典,数据是总是复制,因为它转化为一个ndarray。

然而,有一种方式来获得这种类型的动态行为,以有限的方式。

In [9]: arr = np.array(np.random.rand(5,2)) 

In [10]: df = DataFrame(arr) 

In [11]: arr[0,0] = 0 

In [12]: df 
Out[12]: 
      0   1 
0 0.000000 0.192056 
1 0.847185 0.609028 
2 0.833997 0.422521 
3 0.937638 0.711856 
4 0.047569 0.033282 

因此,通过的ndarray将在构建时成为底层numpy数组的视图。根据您在DataFrame上的操作方式,您可以触发一个副本(例如,如果您指定说一个新列或更改列dtype)。这也只适用于单个dtype帧。

0

能够initalize一个数据帧,而不复制数据。要了解如何,您需要了解BlockManager,它是DataFrame使用的基础数据结构。它试图将相同dtype的数据组合在一起,并将其内存保存在一个块中。如果数据被作为一个单独的块已经提供了,比如你从矩阵初始化:

 a = np.zeros((100,20)) 
     a.flags['WRITEABLE'] = False 
     df = pd.DataFrame(a, copy=False) 
     assert_read_only(df[df.columns[0]].iloc) 

...那么数据帧可以通常只是引用ndarray。

显然,这是不是如果你开始与多个阵列或具有异质类型要去工作。 在这种情况下,您可以monkey patch the BlockManager,迫使它不整合不同类型的数据。