2017-08-11 4 views
5

Betrachten Sie die folgende hdfstore und Datenrahmen df und df2Kann ich einen HDFStore aktualisieren?

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 

Ich möchte zuerst df in den Laden schreiben.

store.append('df', df) 

store.get('df') 

    C 
A B 
0 X 0 
    Y 1 
    Z 2 
1 X 3 
    Y 4 
    Z 5 

Zu einem späteren Zeitpunkt wird habe ich eine andere Datenrahmen, die ich mit in den Laden aktualisieren möchten. Ich möchte die Zeilen mit den gleichen Indexwerten wie in meinem neuen Datenrahmen überschreiben, während die alten beibehalten werden.

Als ich

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 

dies tun, ist nicht das, was ich will. Beachten Sie, dass (0, 'X') und (1, 'X') wiederholt werden. Ich kann den kombinierten Datenrahmen manipulieren und überschreiben, aber ich erwarte, mit vielen Daten zu arbeiten, wo dies nicht möglich wäre.

Wie aktualisiere ich den Laden zu bekommen?

 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 

Sie werden feststellen, dass 'A', von 'Y' Für jede Ebene sehen und "Z' sind die gleichen, 'V' und 'W' neu sind, und 'X' aktualisiert wird.

Was ist der richtige Weg, dies zu tun?

+0

können Sie arbeiten mit normalen (nicht Multiindex) Indizes? – MaxU

+0

Ja ... meine echten Daten haben Multiindex, aber wenn Sie etwas mit einem einzigen Index zeigen, bin ich damit zufrieden. – piRSquared

+0

OK, ich brauche etwas Zeit für die Vorbereitung einer Demo ... – MaxU

Antwort

3

Idee: Entfernen Sie übereinstimmende Zeilen (mit übereinstimmenden Indexwerten) zuerst aus dem HDF und hängen Sie dann df2 an HDFStore an.

Problem: Ich konnte where="index in df2.index" für Multi-Index-Indizes nicht finden.

Lösung: erste Konvertit multiindexes zu Normalen:

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) 

ergibt dies:

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 

stellen Sie sicher, dass Sie verwenden format='t' und data_columns=True (dies wird Index speichern Index und der Index alle Spalten in der HDF5-Datei, so dass wir sie in der where -Klausel verwenden können, wenn Sie HDF5-Dateien erstellen/anhängen:

store = pd.HDFStore('d:/temp/test1.h5') 
store.append('df', df, format='t', data_columns=True) 
store.close() 

jetzt können wir zuerst die Zeilen aus dem HDFStore mit passenden Indizes entfernen:

store = pd.HDFStore('d:/temp/test1.h5') 

In [345]: store.remove('df', where="index in df2.index") 
Out[345]: 2 

und hängen df2:

In [346]: store.append('df', df2, format='t', data_columns=True, append=True) 

Ergebnis:

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

Vielen Dank! Ich habe dort viel gelernt. Ich habe jetzt ein paar Ideen. Ich melde mich zurück. – piRSquared

+0

@piRSquared, froh, wenn es hilft. Ja, bitte geben Sie ein kurzes Feedback zu Ihrer endgültigen Lösung. Dies wird auch denen helfen, die das gleiche Problem haben ... – MaxU

+0

Es gibt ein Problem mit der 'where =" index in df.index "' -Syntax. Eine Erläuterung und Abhilfe finden Sie unter Pandas [Fehler # 17567] (https://github.com/pandas-dev/pandas/issues/17567). –

Verwandte Themen