如何用Python将多级列Pandas DataFrame转为单级列DataFrame
Pandas多级列DataFrame格式转换方案
针对你描述的多级列结构(含日期层级、子指标列,以及基础维度列),可以通过stack结合数据拼接实现转换,以下是具体实现代码和说明:
1. 模拟你的原始数据结构
先构造一个和你描述一致的多级列DataFrame,方便你对应自己的实际数据:
import pandas as pd # 构造多级列索引:基础列的子层级为空,日期列的子层级为指标名 cols = pd.MultiIndex.from_tuples([ ('Market', ''), ('Product', ''), ('City', ''), ('Territory', ''), ('23-Jan', 'VALUES'), ('23-Jan', 'Values MARKET SHARE'), ('23-Feb', 'VALUES'), ('23-Feb', 'Values MARKET SHARE'), ], names=['TopLevel', 'SubLevel']) # 构造示例数据 data = [ ['APAC', 'X', 'Shanghai', 'East', 100, 0.2, 150, 0.25], ['APAC', 'Y', 'Beijing', 'North', 200, 0.3, 250, 0.35] ] raw_df = pd.DataFrame(data, columns=cols)
2. 转换函数实现
def reshape_multi_col_df(raw_df): # 分离基础维度列和日期相关数据列 base_col_mask = raw_df.columns.get_level_values('TopLevel').isin( ['Market', 'Product', 'City', 'Territory'] ) base_cols = raw_df.columns[base_col_mask] data_cols = raw_df.columns[~base_col_mask] # 提取基础维度数据(后续每个日期行都会复用这些维度值) base_df = raw_df[base_cols].droplevel('SubLevel', axis=1) # 将日期层级从列转成行,同时展开子指标列 data_df = raw_df[data_cols].stack(level='TopLevel').reset_index() data_df = data_df.rename(columns={'TopLevel': 'Date'}) # 复用基础维度数据,确保每个日期对应一行完整维度数据 repeated_base_df = base_df.loc[ base_df.index.repeat(len(data_df['Date'].unique())) ].reset_index(drop=True) # 合并并调整列顺序 result_df = pd.concat([repeated_base_df, data_df], axis=1) # 动态生成列顺序(避免硬编码指标名) desired_order = ( base_df.columns.tolist() + ['Date'] + data_df.columns.drop(['level_0', 'Date']).tolist() ) result_df = result_df[desired_order] # 可选:将日期字符串转为datetime格式 # result_df['Date'] = pd.to_datetime(result_df['Date'], format='%y-%b') return result_df
3. 调用函数并查看结果
final_df = reshape_multi_col_df(raw_df) print(final_df)
输出结果:
Market Product City Territory Date VALUES Values MARKET SHARE 0 APAC X Shanghai East 23-Jan 100 0.2 1 APAC X Shanghai East 23-Feb 150 0.25 2 APAC Y Beijing North 23-Jan 200 0.3 3 APAC Y Beijing North 23-Feb 250 0.35
关键注意事项
- 如果你的基础列也是多级结构,只需调整
droplevel的参数或改用rename来简化列名 - 若日期格式需要统一(如转为datetime),取消函数中对应注释行即可
- 若子指标列不固定,代码中已通过动态获取列名适配,无需硬编码
内容的提问来源于stack exchange,提问作者Gojoe
相关产品推荐
相关产品推荐

