Могу ли я обновить 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
Другие вопросы по тегам