如何理解Pandas文档中MultiIndex部分层级关联的说明?
当仅使用MultiIndex的部分层级关联DataFrame时,结果中多余的层级会被丢弃。如需保留这些层级,请在关联前使用DataFrame.reset_index()将这些层级转换为列。
如何理解这段Pandas文档说明?
在我自己的测试示例中,用左表MultiIndex的abc、xy层级关联右表的对应层级,结果里左表的num层级仍然存在且值被广播,这和文档描述的“多余层级被丢弃”不符,我还测试了如果右侧索引不是左侧索引的子集,即便用on指定共同索引也会报错,测试代码如下:
In [109]: leftindex = pd.MultiIndex.from_product( .....: [list("abc"), list("xy"), [1, 2]], names=["abc", "xy", "num"] .....: ) .....: In [110]: left = pd.DataFrame({"v1": range(12)}, index=leftindex) In [111]: left Out[111]: v1 abc xy num a x 1 0 2 1 y 1 2 2 3 b x 1 4 2 5 y 1 6 2 7 c x 1 8 2 9 y 1 10 2 11 In [112]: rightindex = pd.MultiIndex.from_product( .....: [list("abc"), list("xy")], names=["abc", "xy"] .....: ) .....: In [113]: right = pd.DataFrame({"v2": [100 * i for i in range(1, 7)]}, index=rightindex) In [114]: right Out[114]: v2 abc xy a x 100 y 200 b x 300 y 400 c x 500 y 600 In [115]: left.join(right, on=["abc", "xy"], how="inner") Out[115]: v1 v2 abc xy num a x 1 0 100 2 1 100 y 1 2 200 2 3 200 b x 1 4 300 2 5 300 y 1 6 400 2 7 400 c x 1 8 500 2 9 500 y 1 10 600 2 11 600
核心理解:文档描述的是「被关联表」的多余层级处理逻辑
文档里的“多余层级被丢弃”,针对的是被用来关联的那个DataFrame(通常是右表)中未被用作关联键的索引层级,而非发起关联的左表的索引层级。
你的示例为什么没触发“层级丢弃”?
你的测试中:
- 右表的所有索引层级(
abc、xy)都被用作关联键,没有多余层级,自然不会被丢弃; - 左表的
num层级是自身索引的一部分,并非关联键,但左表是关联操作的基准表,它的完整索引会被保留在结果中,右表的对应值会自动广播到左表的每一行——这就是你看到num仍然存在的原因。
触发文档描述场景的典型例子
假设右表是三层MultiIndex,我们仅用其中一层关联左表:
# 左表:单层索引abc left = pd.DataFrame({"v1": [0, 1, 2]}, index=pd.Index(["a", "b", "c"], name="abc")) # 右表:三层MultiIndex(abc、xy、num) rightindex = pd.MultiIndex.from_product( [list("abc"), list("xy"), [1, 2]], names=["abc", "xy", "num"] ) right = pd.DataFrame({"v2": range(12)}, index=rightindex) # 仅用右表的abc层级关联左表 result = left.join(right, on="abc")
此时右表的xy、num属于未被使用的多余层级,它们不会保留在结果的索引里,而是会转为普通列:
v1 xy num v2 abc a 0 x 1 0 a 0 x 2 1 a 0 y 1 2 a 0 y 2 3 b 1 x 1 4 b 1 x 2 5 b 1 y 1 6 b 1 y 2 7 c 2 x 1 8 c 2 x 2 9 c 2 y 1 10 c 2 y 2 11
如何保留多余层级?
按照文档提示,先把被关联表的多余索引层级转为列,关联后再重新设置索引:
right_reset = right.reset_index() result = left.join(right_reset, on="abc").set_index(["abc", "xy", "num"])
最终结果的索引会保留所有层级:
v1 v2 abc xy num a x 1 0 0 2 0 1 y 1 0 2 2 0 3 b x 1 1 4 2 1 5 y 1 1 6 2 1 7 c x 1 2 8 2 2 9 y 1 2 10 2 2 11
总结
- 左表的未关联索引层级会被保留,因为它是关联的基准;
- 被关联表(右表)的未关联索引层级会被丢弃,不会保留在结果索引中;
- 若要保留被关联表的多余层级,需先通过
reset_index()将其转为列,关联后再恢复为索引。
内容的提问来源于stack exchange,提问作者kkk su
相关产品推荐
相关产品推荐

