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

如何构建以原列为顶层、含计算列的多级索引Pandas DataFrame?

问题描述

现有输入DataFrame如下:

index      |        col_1            |           col_2             |
         1         |        1234             |           4567              |
         2         |        3456             |           9453              |

该DataFrame的每一列均为时间序列,需对每列执行计算生成等长序列(例如计算最近5个样本的滑动均值opr_1、最近10个样本的滑动均值opr_2),最终输出需按原列名分组,结构如下:

Output:

                   |        col_1          |          col_2        |
        index      | value   opr_1   opr_2 | value   opr_1   opr_2 |
         1         | 1234     10       1   | 4567     22       13  |
         2         | 3456     18       6   | 9453     21       4   |

要求可通过df['col_1']['value']这类方式访问原列及其相关计算结果。

尝试过两种方案但均遇问题:

  1. 手动提升索引层级:
df.columns = pd.MultiIndex.from_product([df.columns, ['value']])

无法仅对第二层执行apply操作,也不知道如何将计算结果存入df['col_1']['opr_1']层级中。
2. 为每个计算生成单独的DataFrame:

opr_1 = df.apply(lambda x: opr_1_func(x, **params))
opr_2 = df.apply(lambda x: opr_2_func(x, **params))

不知如何拼接这三个DataFrame以得到目标多级索引结构。

解决方案

要实现目标的多级索引结构,可通过构造带多级索引列的DataFrame并横向拼接完成,具体步骤如下:

1. 转换原始数据为多级索引列

先将原始DataFrame的列重构为(原列名, 'value')的多级索引形式,保留原始值:

df_raw = df.copy()
# 生成(列名, 'value')的元组作为多级列名
df_raw.columns = pd.MultiIndex.from_tuples([(col, 'value') for col in df_raw.columns])

2. 为计算结果添加对应多级索引

对每个操作生成结果后,为结果列赋予(原列名, 操作名)的多级索引,确保后续拼接时能对应到正确的原列下:

# 生成opr_1计算结果,设置多级列名
opr_1 = df.apply(lambda x: opr_1_func(x, **params))
opr_1.columns = pd.MultiIndex.from_tuples([(col, 'opr_1') for col in opr_1.columns])

# 生成opr_2计算结果,设置多级列名
opr_2 = df.apply(lambda x: opr_2_func(x, **params))
opr_2.columns = pd.MultiIndex.from_tuples([(col, 'opr_2') for col in opr_2.columns])

3. 拼接所有DataFrame并整理结构

使用pd.concat横向拼接原始数据和两个计算结果的DataFrame,再按一级列名排序,保证同一原列的子列(value、opr_1、opr_2)排列在一起:

result = pd.concat([df_raw, opr_1, opr_2], axis=1)
# 按一级列名排序,规整结构
result = result.sort_index(axis=1, level=0)

完成后,即可通过result['col_1']['value']、result['col_1']['opr_1']这类方式直接访问对应数据,完全匹配需求。

替代方案:逐列构造再合并

如果觉得上述步骤不够直观,也可以遍历每个原列,单独构造该列的所有子列后再合并:

result_dfs = []
for col in df.columns:
    # 提取原始值并设置多级索引名
    value_series = df[col].rename((col, 'value'))
    # 计算opr_1并设置索引名
    opr1_series = opr_1_func(df[col], **params).rename((col, 'opr_1'))
    # 计算opr_2并设置索引名
    opr2_series = opr_2_func(df[col], **params).rename((col, 'opr_2'))
    # 拼接当前列的所有子列
    col_df = pd.concat([value_series, opr1_series, opr2_series], axis=1)
    result_dfs.append(col_df)

# 合并所有列的DataFrame
result = pd.concat(result_dfs, axis=1)

这种方式逻辑更清晰,也能严格保证每列的子列顺序符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 19:25:20