我可以更新 HDFStore 吗?
Can I update an HDFStore?
考虑以下 hdfstore
和数据帧 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。
问题:我找不到将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
确保你使用format='t'
和data_columns=True
(这将索引保存索引和索引所有列在HDF5文件中,允许我们使用它们在 where
子句中)当你 create/append 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
考虑以下 hdfstore
和数据帧 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。
问题:我找不到将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
确保你使用format='t'
和data_columns=True
(这将索引保存索引和索引所有列在HDF5文件中,允许我们使用它们在 where
子句中)当你 create/append 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