我可以更新HDFStore吗?

问题描述:

考虑以下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

构想:先从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)。 –