2013-04-30 96 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,迫使它不整合不同類型的數據。