有没有办法在不重置索引的情况下在MultiIndex的单个级别上进行合并?
我有一个时间不变值的“静态”表,由ObjectID索引,我有一个时变字段的“动态”表,由ObjectID + Date索引。我想一起加入这些表格。
现在,我能想到的最好的是:
dynamic.reset_index().merge(static, left_on=['ObjectID'], right_index=True)
然而,动态表格非常大,我不想让它的索引粘在一起以便合并这些值。
答案 0 :(得分:18)
是的,因为pandas 0.14.0,现在可以使用.join
将单个索引的DataFrame与多索引DataFrame的级别合并。
df1.join(df2, how='inner') # how='outer' keeps all records from both data frames
The 0.14 pandas docs将此描述为等效,但内存效率更高,速度更快:
merge(df1.reset_index(),
df2.reset_index(),
on=['index1'],
how='inner'
).set_index(['index1','index2'])
文档还提到.join
不能用于在单个级别上合并两个多索引的DataFrame,也不能用于上一期的GitHub跟踪器讨论,看起来这可能不是优先实现的:
所以我合并了单一联接,见#6363;以及一些文档 如何进行多重连接。这实际上相当复杂 实行。和恕我直言,不值得努力,因为它真的不会改变 内存使用/速度很多。
然而,有一个关于此的GitHub对话,其中有一些最近的发展https://github.com/pydata/pandas/issues/6360。也可以通过重置前面提到的和文档中描述的索引来实现这一点。
现在可以将多索引数据帧相互合并。根据{{3}}:
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]
答案 1 :(得分: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))
答案 2 :(得分:1)
我会将映射用于单个列:
df1['newcol'] = df1.index.get_level_values(-1).map(lambda x: df2.newcol[x])
答案 3 :(得分:1)
这对我有用!
gData.columns = gData.columns.droplevel(0)
grpData = gData.reset_index()
grpData
pd.merge(grpData,cusData,how='inner')
此处,gData是具有两个级别的多索引数据帧,而cusData是单个索引数据帧。