使用unstack()重塑Pandas DataFrame时的列头重排问题
解决Pandas unstack()后列层级排列问题
我来帮你搞定这个Pandas列层级的问题!首先咱们先把场景理清楚,你给出的列表转成DataFrame后,应该是包含类别、供应商、区域、年份和数值这几列的结构。用unstack()后出现多级列头,本质是因为unstack把索引的某个层级转成了列,导致列变成了多级索引,咱们一步步来解决:
第一步:构建初始DataFrame
先把你提供的列表转换成结构清晰的DataFrame,方便后续操作:
from pandas import DataFrame fList = [ ['Packs', 'Brablik', 'Holesovice', '2017', 100], ['Decorations', 'Drapp-design', 'Holesovice', '2017', 150], ['Decorations', 'Klapetkovi', 'Holesovice', '2017', 200], ['Decorations', 'Lezecké dárky', 'Fler', '2017', 100] ] # 给列命名,让数据结构更清晰 df = DataFrame(fList, columns=['Category', 'Supplier', 'Location', 'Year', 'Value'])
第二步:理解unstack()产生多级列的原因
假设你是先设置了多级索引再执行unstack,比如这样的操作:
# 设置多级索引,然后针对Supplier层级unstack df_unstacked = df.set_index(['Category', 'Location', 'Year', 'Supplier'])['Value'].unstack('Supplier')
如果你的数据存在多个层级的unstack(比如同时unstack年份和供应商),就会产生多级列索引。
第三步:重新排列/扁平化列头
根据你的需求,这里提供两种常用的处理方式:
方式1:扁平化多级列头
把多级列合并成单个列名,用分隔符(比如下划线、空格)连接:
# 用下划线合并多级列名 df_unstacked.columns = ['_'.join(col) for col in df_unstacked.columns.values] # 或者用空格连接 # df_unstacked.columns = df_unstacked.columns.map(' '.join)
方式2:调整列层级顺序并排序
如果想保留多级列,但调整层级的先后顺序,可以用swaplevel()交换层级,再排序:
# 假设列层级是(Year, Supplier),交换成(Supplier, Year) df_unstacked = df_unstacked.swaplevel(0, 1, axis=1) # 按列层级排序,让结构更规整 df_unstacked = df_unstacked.sort_index(axis=1)
方式3:填充缺失值(可选)
unstack后经常会出现NaN(表示该组合没有数据),如果需要可以填充为0或其他默认值:
df_unstacked = df_unstacked.fillna(0)
完整示例流程
这里给一个包含unstack、处理列层级的完整代码:
from pandas import DataFrame # 创建初始DataFrame fList = [ ['Packs', 'Brablik', 'Holesovice', '2017', 100], ['Decorations', 'Drapp-design', 'Holesovice', '2017', 150], ['Decorations', 'Klapetkovi', 'Holesovice', '2017', 200], ['Decorations', 'Lezecké dárky', 'Fler', '2017', 100], ['Packs', 'Brablik', 'Fler', '2018', 120] ] df = DataFrame(fList, columns=['Category', 'Supplier', 'Location', 'Year', 'Value']) # 设置多级索引并unstack两个层级,产生多级列 df_multi = df.set_index(['Category', 'Location'])['Value'].unstack(['Supplier', 'Year']) # 扁平化列名 df_multi.columns = ['{}_{}'.format(supplier, year) for supplier, year in df_multi.columns] # 重置索引,把原索引列转为普通列 df_final = df_multi.reset_index() print("处理后的最终DataFrame:") print(df_final)
内容的提问来源于stack exchange,提问作者New2coding
相关产品推荐
相关产品推荐

