如何将Pandas复合列的末尾层级提取为独立列并重塑DataFrame?
处理Pandas复合元组列名,提取过滤列并重塑DataFrame
需求说明:
针对以元组作为复合列名的Pandas DataFrame,需要完成以下操作:
- 将每个复合列的最后2个层级提取为独立的
Filter1、Filter2列 - 将复合列的**前半部分(除最后两层外)**保留为单个列(元组格式)
- 支持同时处理多组不同前缀的复合列(比如
(ATop, AMiddle, ABottom)和(BTop, BMiddle, BBottom)这类不同前缀)
解决方案代码
先针对示例输入处理:
import pandas as pd input_df = pd.DataFrame({ 'Index': [1], ("ATop", "AMiddle", "ABottom", "filt1_1", "filt2_1"): ["Value 1"], ("ATop", "AMiddle", "ABottom", "filt1_2", "filt2_2"): ["Value 2"] }) # 1. 分离普通列与复合列 id_cols = [col for col in input_df.columns if not isinstance(col, tuple)] tuple_cols = [col for col in input_df.columns if isinstance(col, tuple)] # 2. 逐个处理复合列,拆分前缀与过滤项 processed_dfs = [] for col in tuple_cols: # 提取前缀(除最后两层外的所有层级) prefix = col[:-2] # 提取最后两层作为Filter1、Filter2的值 filter1_val = col[-2] filter2_val = col[-1] # 生成临时DataFrame,重命名复合列并添加过滤列 temp_df = input_df[id_cols + [col]].rename(columns={col: prefix}) temp_df['Filter1'] = filter1_val temp_df['Filter2'] = filter2_val processed_dfs.append(temp_df) # 3. 合并所有临时结果,重置索引 expected_df = pd.concat(processed_dfs, ignore_index=True) print(expected_df)
输出结果与预期完全一致:
Index (ATop, AMiddle, ABottom) Filter1 Filter2 0 1 Value 1 filt1_1 filt2_1 1 1 Value 2 filt1_2 filt2_2
扩展支持多组复合列
如果输入包含多组不同前缀的复合列,代码无需修改即可直接处理:
# 多组复合列的测试输入 input_df_multi = pd.DataFrame({ 'Index': [1, 2], ("ATop", "AMiddle", "ABottom", "filt1_1", "filt2_1"): ["Value A1", "Value A1_2"], ("ATop", "AMiddle", "ABottom", "filt1_2", "filt2_2"): ["Value A2", "Value A2_2"], ("BTop", "BMiddle", "BBottom", "filtB_1", "filtB_2"): ["Value B1", "Value B1_2"], ("BTop", "BMiddle", "BBottom", "filtB_3", "filtB_4"): ["Value B2", "Value B2_2"] }) # 复用上述处理逻辑 id_cols = [col for col in input_df_multi.columns if not isinstance(col, tuple)] tuple_cols = [col for col in input_df_multi.columns if isinstance(col, tuple)] processed_dfs = [] for col in tuple_cols: prefix = col[:-2] filter1_val = col[-2] filter2_val = col[-1] temp_df = input_df_multi[id_cols + [col]].rename(columns={col: prefix}) temp_df['Filter1'] = filter1_val temp_df['Filter2'] = filter2_val processed_dfs.append(temp_df) result_df = pd.concat(processed_dfs, ignore_index=True) print(result_df)
关键逻辑说明
- 自动区分普通列(如
Index)和复合列(元组格式列名),避免误处理常规列 - 通过切片
col[:-2]提取前缀,无需关心前缀的层级数量,适配任意长度的复合前缀 - 每个复合列单独生成临时DataFrame后合并,确保数据结构统一,实现宽表到长表的重塑
内容的提问来源于stack exchange,提问作者georgi koyrushki
相关产品推荐
相关产品推荐

