it-swarm.com.de

Zusammenführen auf einer Ebene von MultiIndex

Gibt es eine Möglichkeit, auf einer einzigen Ebene eines MultiIndex zusammenzuführen, ohne den Index zurückzusetzen?

Ich habe eine "statische" Tabelle mit zeitinvarianten Werten, die durch eine ObjectID indiziert wird, und ich habe eine "dynamische" Tabelle mit zeitveränderlichen Feldern, die mit ObjectID + Date indiziert sind. Ich möchte diese Tische zusammenfügen.

Im Moment kann ich mir am besten vorstellen:

dynamic.reset_index().merge(static, left_on=['ObjectID'], right_index=True)

Die dynamische Tabelle ist jedoch sehr groß, und ich möchte nicht mit ihrem Index herumspielen, um die Werte zu kombinieren.

26

Ja, seit Pandas 0.14.0 ist es jetzt möglich, einen einfach indizierten DataFrame mit einem Level eines mehrfach indizierten DataFrames mithilfe von .join zusammenzuführen.

df1.join(df2, how='inner') # how='outer' keeps all records from both data frames

Die 0,14 Pandas docs beschreibt dies als äquivalent, jedoch speichereffizienter und schneller als:

merge(df1.reset_index(),
      df2.reset_index(),
      on=['index1'],
      how='inner'
     ).set_index(['index1','index2'])

Die Dokumente erwähnen auch, dass .join nicht verwendet werden kann, um zwei mehrfach indizierte DataFrames auf einer einzigen Ebene und aus der GitHub-Tracker-Diskussion für die vorherige Ausgabe zusammenzuführen.

also habe ich mich im Single Join zusammengeschlossen, siehe # 6363; zusammen mit einigen Dokumenten auf wie man einen Multi-Multi-Join macht. Das ist ziemlich kompliziert, um tatsächlich Umzusetzen. und meiner Meinung nach lohnt sich die Mühe nicht, da sie die Speicherauslastung/Geschwindigkeit nicht so sehr ändert.

Es gibt jedoch eine GitHub-Konversation in dieser Hinsicht, bei der kürzlich etwas weiterentwickelt wurde https://github.com/pydata/pandas/issues/6360 . Dies kann auch durch Zurücksetzen der Indizes erreicht werden, wie zuvor erwähnt und auch in den Dokumenten beschrieben.

17
joelostblom

Ich umgehe dies, indem ich das Zusammenfügen des Datenrahmens zum vollständigen Multiindex neu indexiere, so dass ein Links-Join möglich ist.

# Create the left data frame
import pandas as pd
idx = pd.MultiIndex(levels=[['a','b'],['c','d']],labels=[[0,0,1,1],[0,1,0,1]], names=['lvl1','lvl2'])
df = pd.DataFrame([1,2,3,4],index=idx,columns=['data'])

#Create the factor to join to the data 'left data frame'
newFactor = pd.DataFrame(['fact:'+str(x) for x in df.index.levels[0]], index=df.index.levels[0], columns=['newFactor'])

Führen Sie den Join für den Subindex durch, indem Sie den newFactor-Datenrahmen neu indexieren, um den Index des linken Datenrahmens zu enthalten

df.join(newFactor.reindex(df.index,level=0))
2
closedloop

Das funktioniert bei mir!

gData.columns = gData.columns.droplevel(0)

grpData = gData.reset_index()
grpData

pd.merge(grpData,cusData,how='inner')

Hier ist gData ein Multi-Index-Datenrahmen mit zwei Ebenen und cusData ist ein einzelner Index-Datenrahmen. 

1
Muthu

Ich würde Mapping für eine einzelne Spalte verwenden:

df1['newcol'] = df1.index.get_level_values(-1).map(lambda x: df2.newcol[x])
1
Andor