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

如何将pandas MultiIndex转换为带缩进的单列Index?

问题:将MultiIndex DataFrame转换为带缩进的单层索引格式

我有一个带pandas.MultiIndex的DataFrame:

Vals
Fruits     Apples       a
           Banana       b
Vegetables Tomato       c
           Onion        d
           Potato       e
Foobar     LoreIpsum    f

想要转换成单层索引的形式,要求:

  • 基于第一层级索引插入新行
  • 第二层级索引值添加4个字符的缩进

目标效果如下:

Vals
Fruits
    Apples        a
    Banana        b
Vegetables
    Tomato        c
    Onion         d
    Potato        e
Foobar
    LoreIpsum    f

最小可复现代码:

#!/usr/bin/env python3
import pandas as pd

midx = pd.MultiIndex.from_tuples([
    ('Fruits', 'Apples'),
    ('Fruits', 'Banana'),
    ('Vegetables', 'Tomato'),
    ('Vegetables', 'Onion'),
    ('Vegetables', 'Potato'),
    ('Foobar', 'LoreIpsum')
])
df = pd.DataFrame({'Vals': list('abcdef')}, index=midx)
print(df.to_markdown())

exp_idx = pd.Index([
    'Fruits',
    '    Apples',
    '    Banana',
    'Vegetables',
    '    Tomato',
    '    Onion',
    '    Potato',
    'Foobar',
    '    LoreIpsum',
])
exp_df = pd.DataFrame({'Vals': list(' ab cde f')}, index=exp_idx)
print(exp_df.to_markdown())

解决方案

可以通过重置索引、构造层级行、合并排序的方式实现,全程用pandas内置方法,避免手动循环:

import pandas as pd

# 原始数据
midx = pd.MultiIndex.from_tuples([
    ('Fruits', 'Apples'),
    ('Fruits', 'Banana'),
    ('Vegetables', 'Tomato'),
    ('Vegetables', 'Onion'),
    ('Vegetables', 'Potato'),
    ('Foobar', 'LoreIpsum')
])
df = pd.DataFrame({'Vals': list('abcdef')}, index=midx)

# 1. 拆分MultiIndex为普通列
df_reset = df.reset_index(names=['Level1', 'Level2'])

# 2. 构造第一层级的标题行(子项为空,值为空字符串)
level1_rows = df_reset[['Level1']].drop_duplicates().assign(Level2=pd.NA, Vals='')

# 3. 合并标题行与原始数据行,排序确保标题行在子项上方
combined = pd.concat([level1_rows, df_reset]).sort_values(
    by=['Level1', 'Level2'],
    na_position='first'
)

# 4. 生成最终索引:标题行用Level1值,子项添加4空格缩进
final_index = combined.apply(
    lambda row: row['Level1'] if pd.isna(row['Level2']) else f'    {row["Level2"]}',
    axis=1
)

# 5. 生成目标DataFrame
result_df = combined.set_index(final_index)[['Vals']]

# 输出结果
print(result_df.to_markdown())

步骤说明:

  • 重置索引将多层索引转为普通列,简化后续处理
  • 提取第一层级唯一值构造标题行,保证每个分类都有独立的标题行
  • 合并后排序,让标题行自动排在对应子项的最上方
  • 按规则生成单层索引,实现标题无缩进、子项4空格缩进的格式
  • 重新设置索引后得到符合要求的DataFrame

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 06:27:26