2017-08-11 125 views
5

考慮以下hdfstore和dataframes dfdf2我可以更新HDFStore嗎?

import pandas as pd 

store = pd.HDFStore('test.h5') 

midx = pd.MultiIndex.from_product([range(2), list('XYZ')], names=list('AB')) 
df = pd.DataFrame(dict(C=range(6)), midx) 

df 

    C 
A B 
0 X 0 
    Y 1 
    Z 2 
1 X 3 
    Y 4 
    Z 5 

midx2 = pd.MultiIndex.from_product([range(2), list('VWX')], names=list('AB')) 
df2 = pd.DataFrame(dict(C=range(6)), midx2) 

df2 

    C 
A B 
0 V 0 
    W 1 
    X 2 
1 V 3 
    W 4 
    X 5 

我想先寫df商店。

store.append('df', df) 

store.get('df') 

    C 
A B 
0 X 0 
    Y 1 
    Z 2 
1 X 3 
    Y 4 
    Z 5 

在稍後的時間點,我會說我想更新與賣場的另一個數據幀。我想覆蓋與新數據框中相同索引值的行,同時保留舊數據。

當我做

store.append('df', df2) 

store.get('df') 

    C 
A B 
0 X 0 
    Y 1 
    Z 2 
1 X 3 
    Y 4 
    Z 5 
0 V 0 
    W 1 
    X 2 
1 V 3 
    W 4 
    X 5 

這是不是在所有我想要的東西。請注意,(0, 'X')(1, 'X')重複。我可以操縱組合的數據框並進行覆蓋,但我希望能夠處理大量的數據,這是不可行的。

如何更新商店以獲取?

 C 
A B 
0 V 0 
    W 1 
    X 2 
    Y 1 
    Z 2 
1 V 3 
    W 4 
    X 5 
    Y 4 
    Z 5 

你會看到,對於'A''Y'每一級'Z'是相同的,'V''W'是新的,'X'被更新。

這樣做的正確方法是什麼?

+0

你能工作與正常(而不是多指標)索引? – MaxU

+0

是的......我的真實數據有多重索引,但是如果您使用單一索引顯示某些內容,我對此感到滿意。 – piRSquared

+0

好的,我需要一些時間準備演示... – MaxU

回答

3

構想:先從HDF中刪除匹配的行(具有匹配的索引值),然後將df2附加到HDFStore。

問題:我不能找到一種方法,使用where="index in df2.index"多指數指標。

解決方案:第一轉換multiindexes正常的:

df.index = df.index.get_level_values(0).astype(str) + '_' + df.index.get_level_values(1).astype(str) 

df2.index = df2.index.get_level_values(0).astype(str) + '_' + df2.index.get_level_values(1).astype(str) 

這產生了:

In [348]: df 
Out[348]: 
    C 
0_X 0 
0_Y 1 
0_Z 2 
1_X 3 
1_Y 4 
1_Z 5 

In [349]: df2 
Out[349]: 
    C 
0_V 0 
0_W 1 
0_X 2 
1_V 3 
1_W 4 
1_X 5 

確保您使用format='t'data_columns=True(這將索引存儲索引和索引所有列在HDF5文件中,允許我們在where子句中使用它們)當您創建/附加HDF5文件時:

store = pd.HDFStore('d:/temp/test1.h5') 
store.append('df', df, format='t', data_columns=True) 
store.close() 

現在我們可以先刪除從HDFStore那些行相匹配的指標:

store = pd.HDFStore('d:/temp/test1.h5') 

In [345]: store.remove('df', where="index in df2.index") 
Out[345]: 2 

和追加df2

In [346]: store.append('df', df2, format='t', data_columns=True, append=True) 

結果:

In [347]: store.get('df') 
Out[347]: 
    C 
0_Y 1 
0_Z 2 
1_Y 4 
1_Z 5 
0_V 0 
0_W 1 
0_X 2 
1_V 3 
1_W 4 
1_X 5 
+1

非常感謝!我在那裏學到了很多東西。我現在有一些想法。我會回報。 – piRSquared

+0

@piRSquared,如果有幫助,很高興。是的,請給出關於您最終解決方案的簡短反饋。這也將幫助那些有同樣的問題... – MaxU

+0

沒有與'語法'這裏=「在df.index指數」的問題。有關解釋和解決方法,請參閱熊貓[bug#17567](https://github.com/pandas-dev/pandas/issues/17567)。 –

相關問題