You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将两个关联的Pandas DataFrame合并为多级索引DataFrame?

如何将两个关联DataFrame合并为多级索引DataFrame?

我有两个关联的DataFrame,想找个简便方法把它们合并成以(p,c,a)为多级索引、仅含value列的结构,以下是示例代码和数据:

第一个DataFrame(df)

import pandas as pd
df = pd.DataFrame( [[
   1,0,1,0],
    [1,1,0,0],
    [1,0,0,1],
  [0,1,0,1]], columns=["c1","c2","c3", "c4"]
 )
idx= pd.Index(['p1','p2','p3','p4'])
df = df.set_index(idx)

输出结果:

c1  c2  c3  c4
p1  1   0   1   0
p2  1   1   0   0
p3  1   0   0   1
p4  0   1   0   1

第二个DataFrame(df2)

df2 = pd.DataFrame( [[
   0,10,30,0],
    [20,10,0,0],
    [0,10,0,6],
  [15,0,18,5]], columns=["c1","c2","c3", "c4"]
 )
idx2= pd.Index(['a1','a2','a3','a4'])
df2 = df2.set_index(idx2)

输出结果:

c1  c2  c3  c4
a1  0   10  30  0
a2  20  10  0   0
a3  0   10  0   6
a4  15  0   18  5

期望的最终结果

value
p1  c1  a2  20
        a4  15
    c3  a1  30
        a4  18
p2  c1  a2  20
        a4  15
    c2  a1  10
        a2  10
        a3  10
p3  c1  a2  20
        a4  15
    c4  a3  6
        a4  5
p4  c2  a1  10
        a2  10
        a3  10
    c4  a3  6
        a4  5

解决方案

可以通过重塑数据+筛选匹配项+合并的步骤实现,具体操作如下:

步骤1:将两个DataFrame转为长格式

先把宽格式的df和df2转成长格式,筛选出有效数据:

# 处理df:只保留值为1的记录,提取p和c的对应关系
df_long = df.stack().reset_index()
df_long.columns = ['p', 'c', 'flag']
df_long = df_long[df_long['flag'] == 1].drop('flag', axis=1)

# 处理df2:只保留值非0的记录,提取a、c和对应value
df2_long = df2.stack().reset_index()
df2_long.columns = ['a', 'c', 'value']
df2_long = df2_long[df2_long['value'] != 0]

步骤2:按关联列c合并数据

两个DataFrame通过c列关联,直接用merge合并即可得到所有匹配的组合:

merged = pd.merge(df_long, df2_long, on='c')

步骤3:设置多级索引并排序

把p、c、a设为多级索引,排序后只保留value列:

result = merged.set_index(['p', 'c', 'a']).sort_index()[['value']]

完整代码

import pandas as pd

# 初始化原始数据
df = pd.DataFrame( [[1,0,1,0], [1,1,0,0], [1,0,0,1], [0,1,0,1]], columns=["c1","c2","c3", "c4"] )
idx= pd.Index(['p1','p2','p3','p4'])
df = df.set_index(idx)

df2 = pd.DataFrame( [[0,10,30,0], [20,10,0,0], [0,10,0,6], [15,0,18,5]], columns=["c1","c2","c3", "c4"] )
idx2= pd.Index(['a1','a2','a3','a4'])
df2 = df2.set_index(idx2)

# 转长格式并筛选有效数据
df_long = df.stack().reset_index()
df_long.columns = ['p', 'c', 'flag']
df_long = df_long[df_long['flag'] == 1].drop('flag', axis=1)

df2_long = df2.stack().reset_index()
df2_long.columns = ['a', 'c', 'value']
df2_long = df2_long[df2_long['value'] != 0]

# 合并并生成目标多级索引DataFrame
merged = pd.merge(df_long, df2_long, on='c')
result = merged.set_index(['p', 'c', 'a']).sort_index()[['value']]

print(result)

运行后输出结果与期望完全一致。


内容的提问来源于stack exchange,提问作者simon leung

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 17:40:36