Python 在多索引上使用不同的级别数进行连接

Python 在多索引上使用不同的级别数进行连接,python,pandas,dataframe,join,multi-index,Python,Pandas,Dataframe,Join,Multi Index,如何在多索引上以不同的级别连接2个数据帧 将熊猫作为pd导入 t1=pd.DataFrame(数据={'a1':[0,0,1,1,2,2], “a2”:[0,1,0,1,0,1], ‘x’:[1,2,3,4,5,6.]}) t1.设置索引(['a1','a2'],原地=真) t1.排序索引(就地=真) t2=pd.DataFrame(数据={'b1':[0,1,2], ‘y’:[20,40,60.]}) t2.设置索引(['b1'],原地=真) t2.排序索引(就地=真) >>t1 x a1

如何在多索引上以不同的级别连接2个数据帧

将熊猫作为pd导入
t1=pd.DataFrame(数据={'a1':[0,0,1,1,2,2],
“a2”:[0,1,0,1,0,1],
‘x’:[1,2,3,4,5,6.]})
t1.设置索引(['a1','a2'],原地=真)
t1.排序索引(就地=真)
t2=pd.DataFrame(数据={'b1':[0,1,2],
‘y’:[20,40,60.]})
t2.设置索引(['b1'],原地=真)
t2.排序索引(就地=真)
>>t1
x
a1 a2
0  0   1.0
1   2.0
1  0   3.0
1   4.0
2  0   5.0
1   6.0
>>>t2
Y
b1
0   20.0
1   40.0
2   60.0
在“a1”=>“b1”上加入的预期结果:

xy
a1 a2
0  0   1.0 20.0
1   2.0 20.0
1  0   3.0 40.0
1   4.0 40.0
2  0   5.0 60.0
1   6.0 60.0
另一个例子:在['a1','a2']=>['b1','b2']上连接:

将熊猫作为pd导入,numpy作为np导入
t1=pd.DataFrame(数据={'a1':[0,0,0,1,1,1,1,2,2,2],
‘a2’:[3,3,4,4,3,3,4,4,3,3,3,4,4],
“a3”:[7,8,7,8,7,8,7,8,8,7,8,7,8],
‘x’:[1,2,3,4,5,6,7,8,9,10,11,12.]]
t1.设置索引(['a1'、'a2'、'a3'],原地=真)
t1.排序索引(就地=真)
t2=pd.DataFrame(数据={'b1':[0,0,1,1,2,2],
‘b2’:[3,4,3,4,3,4],
‘y’:[10,20,30,40,50,60.]})
t2.设置索引(['b1','b2'],原地=真)
t2.排序索引(就地=真)
>>t1
x
a1 a2 a3
0  3  7    1.0
8    2.0
4  7    3.0
8    4.0
1  3  7    5.0
8    6.0
4  7    7.0
8    8.0
2  3  7    9.0
8   10.0
4  7   11.0
8   12.0
>>>t2
Y
b1 b2
0  3   10.0
4   20.0
1  3   30.0
4   40.0
2  3   50.0
4   60.0
在['a1','a2']=>['b1','b2']上加入的预期结果:

xy
a1 a2 a3
0  3  7    1.0  10.0
8    2.0  10.0
4  7    3.0  20.0
8    4.0  20.0
1  3  7    5.0  30.0
8    6.0  30.0
4  7    7.0  40.0
8    8.0  40.0
2  3  7    9.0  50.0
8   10.0  50.0
4  7   11.0  60.0
8   12.0  60.0
解决方案应该在多个索引级别上工作

谢谢你的帮助

您可以从
t2
使用并映射序列:

t1['y'] = t1.index.get_level_values(0).map(t2['y'].get)

print(t1)

         x     y
a1 a2           
0  0   1.0  20.0
   1   2.0  20.0
1  0   3.0  40.0
   1   4.0  40.0
2  0   5.0  60.0
   1   6.0  60.0
t1.merge(t2, left_on = t1.index.get_level_values('a1').values, right_index=True)

         x     y
a1 a2           
0  0   1.0  20.0
   1   2.0  20.0
1  0   3.0  40.0
   1   4.0  40.0
2  0   5.0  60.0
   1   6.0  60.0

您可以在
t1
中名为
a1
的索引级别上直接合并
t1
t2
,以及
t2
的单个索引:

t1['y'] = t1.index.get_level_values(0).map(t2['y'].get)

print(t1)

         x     y
a1 a2           
0  0   1.0  20.0
   1   2.0  20.0
1  0   3.0  40.0
   1   4.0  40.0
2  0   5.0  60.0
   1   6.0  60.0
t1.merge(t2, left_on = t1.index.get_level_values('a1').values, right_index=True)

         x     y
a1 a2           
0  0   1.0  20.0
   1   2.0  20.0
1  0   3.0  40.0
   1   4.0  40.0
2  0   5.0  60.0
   1   6.0  60.0
t2
上使用,根据需要设置
级别
参数,并直接分配给
t1

t1['y'] = t2['y'].reindex(t1.index, level='a1')

         x     y
a1 a2           
0  0   1.0  20.0
   1   2.0  20.0
1  0   3.0  40.0
   1   4.0  40.0
2  0   5.0  60.0
   1   6.0  60.0

要在多个级别上重新编制索引,只需传递一个列表作为
level
参数,例如
['a1',a2'
].

在第二个示例中,执行联接的一种缓慢方式:

t2.列中的列的
:
对于t2.index中的i2:
t1.loc[i2+(片(无),列]=t2.loc[i2,列]
任务是将其矢量化,并在创建t1索引项时将切片(无)自动放置在正确的位置

第二个示例的矢量化版本:

m=list(zip(t1.index.get_level_values('a1')、t1.index.get_level_values('a2'))
t1=t1.assign(**dict(zip(t2.columns,[np.nan]*len(t2.columns)))
t1[t2.columns]=t2.loc[m,:]值
第一个示例的矢量化版本:

m=t1.index.get_level_值('a1'))
t1=t1.assign(**dict(zip(t2.columns,[np.nan]*len(t2.columns)))
t1[t2.columns]=t2.loc[m,:]值

第一个示例的解决方案:

t1.重置索引('a2',drop=False).连接(t2)
).重命名_轴('a1')。设置_索引('a2',append=True)
第二个示例的解决方案:

t1.reset_索引('a3',drop=False)。连接(
t2.重命名_轴(索引={'b1':'a1','b2':'a2'})
).set_索引('a3',append=True)

如果t1有3个索引级别,t2有2个索引级别,并且在t2的2个级别上进行连接,是否有办法修改此解决方案,以使其能够工作?@S.V,我相信这是可能的。但这应该作为一个单独的问题来问。这个解决方案看起来最有希望,因为它可以在多索引中的多个级别上使用,但如果我在第二个示例中使用它(在t2中连接两个级别,t1有三个级别):即
t2['y'].reindex(t1.index,级别=['a1','a2'])
给出TypeError:两个多索引对象之间的级别联接不明确。
reindex
不支持级别列表,仅支持单个级别,遗憾的是:(