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

如何高效重塑DataFrame:将分组列转为HH/JJ/KK新列并保留标识列

高效重塑Pandas DataFrame的方法

当然有高效的办法啦!你这种需求属于典型的宽表转长表场景,而且你的列名规律很强(A/B/C前缀加数字后缀),用Pandas自带的工具就能轻松搞定,完全不用写复杂的循环。

我给你两种高效的实现方式,你可以根据自己的习惯选择:

方法一:利用filter+concat快速分组合并

这种方法最直接,利用列名的前缀规律,批量提取每组数据并合并,效率非常高:

首先先构造你的示例DataFrame(方便测试):

import pandas as pd

df = pd.DataFrame({
    'A1': ['a1', 'a4', 'a7'],
    'A2': ['a2', 'a5', 'a8'],
    'A3': ['a3', 'a6', 'a9'],
    'B1': ['b1', 'b4', 'b7'],
    'B2': ['b2', 'b5', 'b8'],
    'B3': ['b3', 'b6', 'b9'],
    'C1': ['c1', 'c4', 'c7'],
    'C2': ['c2', 'c5', 'c8'],
    'C3': ['c3', 'c6', 'c9'],
    'TT': [11, 14, 17],
    'YY': [12, 15, 18],
    'ZZ': [13, 16, 19]
})

然后执行重塑操作:

# 遍历A/B/C三个前缀,分别提取对应列并重命名,再合并TT/YY/ZZ列
result = pd.concat([
    df.filter(regex=f'^{prefix}')  # 提取当前前缀的所有列(比如A1/A2/A3)
      .rename(columns={f'{prefix}1': 'HH', f'{prefix}2': 'JJ', f'{prefix}3': 'KK'})  # 重命名为目标列名
      .join(df[['TT', 'YY', 'ZZ']])  # 合并原有的TT/YY/ZZ列
    for prefix in ['A', 'B', 'C']
], ignore_index=True)  # 合并后重置索引

执行完后,result就是你想要的结构啦!这种方法全程用Pandas的向量化操作,没有逐行循环,数据量越大越能体现效率优势。

方法二:用wide_to_long实现(适合更复杂的列名规律)

如果你的列名规律更复杂,或者需要更灵活的转换,可以用Pandas的wide_to_long函数,不过需要先调整一下列名:

# 先把原列名重命名为「前缀_目标列名」的格式
df_renamed = df.rename(columns={
    'A1': 'A_HH', 'A2': 'A_JJ', 'A3': 'A_KK',
    'B1': 'B_HH', 'B2': 'B_JJ', 'B3': 'B_KK',
    'C1': 'C_HH', 'C2': 'C_JJ', 'C3': 'C_KK'
})

# 使用wide_to_long转换,把前缀(A/B/C)转成行维度
result = pd.wide_to_long(
    df_renamed,
    stubnames=['HH', 'JJ', 'KK'],  # 目标列的前缀
    i=['TT', 'YY', 'ZZ'],  # 保留的索引列(不需要转换的列)
    j='group',  # 临时生成的分组列(后面可以删掉)
    sep='_',  # 列名的分隔符
    suffix='.+'  # 匹配列名的后缀
).reset_index().drop('group', axis=1)  # 重置索引并删除临时分组列

这个方法的优势是扩展性更强,比如如果以后新增D1/D2/D3列,只需要在重命名的时候加上对应映射即可。

两种方法都能高效实现你的需求,第一种更简洁直接,第二种更灵活,你可以根据实际情况选择~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 08:42:39