请考虑以下hdfstore和dataframes df和df2
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’是更新的.
这样做的正确方法是什么?
最佳答案
想法:首先从HDF中删除匹配的行(具有匹配的索引值),然后将df2附加到HDFStore.
原文链接:https://www.f2er.com/python/438782.html问题:对于多索引索引,我找不到使用where =“index in df2.index”的方法.
解决方案:首先将多索引转换为普通索引:
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
确保在创建/附加HDF5文件时使用format =’t’和data_columns = True(这将索引保存索引并索引HDF5文件中的所有列,允许我们在where子句中使用它们):
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,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