Могу ли я обновить 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'
обновляется.
Как правильно это сделать?
1 ответ
Идея: сначала удалить соответствующие строки (с соответствующими значениями индекса) из 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
пункт) при создании / добавлении файлов HDF5:
store = pd.HDFStore('d:/temp/test1.h5')
store.append('df', df, format='t', data_columns=True)
store.close()
теперь мы можем сначала удалить эти строки из хранилища HDFS с соответствующими индексами:
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