37

有没有办法在不重置索引的情况下合并单个级别的 MultiIndex?

我有一个由 ObjectID 索引的时不变值的“静态”表,并且我有一个由 ObjectID+Date 索引的时变字段的“动态”表。我想将这些表连接在一起。

目前,我能想到的最好的是:

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

但是,动态表非常大,我不想为了组合值而不得不使用它的索引。

4

4 回答 4

27

是的,从 pandas 0.14.0 开始,现在可以使用.join.

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

0.14 pandas 文档将其描述为等效但内存效率更高且速度更快:

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

文档还提到.join不能用于在一个级别上合并两个多索引数据帧,并且从上一期的 GitHub 跟踪器讨论中,似乎这可能不是优先实现的:

所以我在单连接中合并,参见#6363;以及一些关于如何进行多重连接的文档。实际实现起来相当复杂。恕我直言,不值得付出努力,因为它根本不会改变内存使用/速度。

但是,有一个关于此的 GitHub 对话,其中有一些最近的开发https://github.com/pydata/pandas/issues/6360。也可以通过重置前面提到的索引以及文档中的描述来实现这一点。


熊猫更新 >= 0.24.0

现在可以将多索引数据帧相互合并。根据发行说明

index_left = pd.MultiIndex.from_tuples([('K0', 'X0'), ('K0', 'X1'),
                                        ('K1', 'X2')],
                                        names=['key', 'X'])

left = pd.DataFrame({'A': ['A0', 'A1', 'A2'],
                     'B': ['B0', 'B1', 'B2']}, index=index_left)

index_right = pd.MultiIndex.from_tuples([('K0', 'Y0'), ('K1', 'Y1'),
                                        ('K2', 'Y2'), ('K2', 'Y3')],
                                        names=['key', 'Y'])

right = pd.DataFrame({'C': ['C0', 'C1', 'C2', 'C3'],
                      'D': ['D0', 'D1', 'D2', 'D3']}, index=index_right)

left.join(right)

出去:

            A   B   C   D
key X  Y                 
K0  X0 Y0  A0  B0  C0  D0
    X1 Y0  A1  B1  C0  D0
K1  X2 Y1  A2  B2  C1  D1

[3 rows x 4 columns]
于 2014-03-12T22:31:00.293 回答
2

我通过重新索引数据框合并以具有完整的多索引来解决此问题,以便可以进行左连接。

# 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'])

通过重新索引 newFactor 数据帧以包含左侧数据帧的索引,对子索引进行连接

df.join(newFactor.reindex(df.index,level=0))
于 2014-01-07T15:57:34.187 回答
2

我会为单个列使用映射:

df1['newcol'] = df1.index.get_level_values(-1).map(lambda x: df2.newcol[x])
于 2017-10-26T12:14:31.193 回答
1

这对我有用!

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

grpData = gData.reset_index()
grpData

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

这里 gData 是具有两个级别的多索引数据帧,而 cusData 是单索引数据帧。

于 2018-06-21T17:33:32.787 回答