2013-08-18 23 views
2

我想連接兩個熊貓DataFrames而不復制數據。也就是說,我想連接的DataFrame是兩個原始DataFrame中數據的視圖。我嘗試使用concat(),並沒有工作。這個代碼塊顯示了改變的基礎數據會影響被級聯兩個DataFrames但不是級聯數據幀:如何連接pandas DataFrame而不復制數據?

arr = np.random.randn(12).reshape(6, 2) 
df = pd.DataFrame(arr, columns = ('VALE5', 'PETR4'), index = dates) 
arr2 = np.random.randn(12).reshape(6, 2) 
df2 = pd.DataFrame(arr, columns = ('AMBV3', 'BBDC4'), index = dates) 
df_concat = pd.concat(dict(A = df, B = df2),axis=1) 
pp(df) 
pp(df_concat) 
arr[0, 0] = 9999999.99 
pp(df) 
pp(df_concat) 

這是最後五行的輸出。在將新值分配給arr [0,0]後,df發生了變化; df_concat不受影響。

In [56]: pp(df) 
      VALE5  PETR4 
2013-01-01 -0.557180 0.170073 
2013-01-02 -0.975797 0.763136 
2013-01-03 -0.913254 1.042521 
2013-01-04 -1.973013 -2.069460 
2013-01-05 -1.259005 1.448442 
2013-01-06 -0.323640 0.024857 

In [57]: pp(df_concat) 
       A     B   
      VALE5  PETR4  AMBV3  BBDC4 
2013-01-01 -0.557180 0.170073 -0.557180 0.170073 
2013-01-02 -0.975797 0.763136 -0.975797 0.763136 
2013-01-03 -0.913254 1.042521 -0.913254 1.042521 
2013-01-04 -1.973013 -2.069460 -1.973013 -2.069460 
2013-01-05 -1.259005 1.448442 -1.259005 1.448442 
2013-01-06 -0.323640 0.024857 -0.323640 0.024857 

In [58]: arr[0, 0] = 9999999.99 

In [59]: pp(df) 
       VALE5  PETR4 
2013-01-01 9999999.990000 0.170073 
2013-01-02  -0.975797 0.763136 
2013-01-03  -0.913254 1.042521 
2013-01-04  -1.973013 -2.069460 
2013-01-05  -1.259005 1.448442 
2013-01-06  -0.323640 0.024857 

In [60]: pp(df_concat) 
       A     B   
      VALE5  PETR4  AMBV3  BBDC4 
2013-01-01 -0.557180 0.170073 -0.557180 0.170073 
2013-01-02 -0.975797 0.763136 -0.975797 0.763136 
2013-01-03 -0.913254 1.042521 -0.913254 1.042521 
2013-01-04 -1.973013 -2.069460 -1.973013 -2.069460 
2013-01-05 -1.259005 1.448442 -1.259005 1.448442 
2013-01-06 -0.323640 0.024857 -0.323640 0.024857 

我猜這意味着concat()創建了一個數據的副本。有沒有辦法避免複製? (我想盡量減少內存使用量)。

另外,有沒有一種快速的方法來檢查兩個數據幀是否鏈接到相同的基礎數據? (經歷了更改數據和檢查每個DataFrame是否已經改變的麻煩)

感謝您的幫助。

FS

+0

當前檢查兩個numpy數組是否共享內存的最佳方法如下所示:http://stackoverflow.com/questions/10747748/how-do-i-check-that-two-slices-of-numpy-數組是相同或重疊的 –

回答

1

你不能(至少很容易)。當您撥打concat時,最終會調用np.concatenate

請參閱this answer explaining why you can't concatenate arrays without copying。缺點是數組不能保證在內存中是連續的。

這裏有一個簡單的例子

a = rand(2, 10) 
x, y = a 
z = vstack((x, y)) 
print 'x.base is a and y.base is a ==', x.base is a and y.base is a 
print 'x.base is z or y.base is z ==', x.base is z or y.base is z 

輸出:

x.base is a and y.base is a == True 
x.base is z or y.base is z == False 

即使xy共享相同的base,即aconcatenate(因此vstack)不能想當然地認爲他們因爲一個做通常想要連接任意跨步的數組。

您可以輕鬆地生成兩個數組不同大步共享相同的存儲,像這樣:

a = arange(10) 
b = a[::2] 
print a.strides 
print b.strides 

輸出:

(8,) 
(16,) 

這就是爲什麼會發生以下情況:

In [214]: a = arange(10) 

In [215]: a[::2].view(int16) 
--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
<ipython-input-215-0366fadb1128> in <module>() 
----> 1 a[::2].view(int16) 

ValueError: new type not compatible with array. 

In [216]: a[::2].copy().view(int16) 
Out[216]: array([0, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0], dtype=int16) 

編輯:使用pd.merge(df1, df2, copy=False)(或df1.merge(df2, copy=False)df1.dtype != df2.dtype不會複製。否則,複製。

+0

這種行爲是一個錯誤嗎? 'merge'有'copy'參數,所以當我做'df_concat = df.merge(df1,left_index = True,right_index = True,copy = False)'如果兩個DataFrames的索引是相同的(在這種情況下是正確的,Series對象不需要改變,爲什麼當我明確地指示它不使用'copy = False'時,大熊貓複製數據?即使我首先創建一個索引,然後創建'df','df'和'df_concat',並且'df.index'是'df_concat.index'返回'True',但數據仍然被複制。 –

+0

我不一定認爲這是一個錯誤。我現在正在研究它。但應該更好地記錄。 –

+0

這不是一個錯誤; concatenate總是複製。沒有辦法維護一個視圖(當然如果你想要關聯原始幀,你可以簡單地設置子視圖)。你究竟想要完成什麼? – Jeff

相關問題