当前位置:首页 > 文章列表 > 文章 > python教程 > Pandas多级列转行索引技巧

Pandas多级列转行索引技巧

2025-12-03 11:36:31 0浏览 收藏

今日不肯埋头,明日何以抬头!每日一句努力自己的话哈哈~哈喽,今天我将给大家带来一篇《Pandas多级列转行索引与列名合并技巧》,主要内容是讲解等等,感兴趣的朋友可以收藏或者有更好的建议在评论提出,我都会认真看的!大家一起进步,一起学习!

Pandas DataFrame高级重塑:将多级列索引转换为行索引与合并列名

本文详细介绍了如何使用Pandas库对DataFrame进行高级重塑操作。我们将一个具有多级列索引(如岛屿和年份)以及月份作为行索引的DataFrame,转换成以岛屿名称作为行索引,并以合并后的月份和年份(例如“JAN2022”)作为单级列索引的新结构。核心步骤包括利用stack()进行堆叠、transpose()进行转置,以及Index.map()来扁平化和自定义列名,从而实现数据的灵活布局。

在数据分析和报告生成中,我们经常需要根据特定的分析需求来重塑Pandas DataFrame的结构。本教程将展示一个常见的重塑场景:如何将一个具有多级列索引(MultiIndex columns)和单级行索引的DataFrame,转换为一个以原始DataFrame的某个列级别作为新的行索引,并将其余索引级别合并为新的单级列索引的DataFrame。

初始DataFrame结构

假设我们有一个DataFrame,其结构如下所示。它包含了不同岛屿(St Thomas, St. Croix)在不同年份(2022, 2023)的月度数据,月份作为行索引。

Island St Thomas         St. Croix        
Year        2022    2023      2022    2023
Month                                     
JAN       55,086  60,470    11,550  12,755
FEB       57,929  56,826    12,441  13,289
MAR       72,103  64,249    14,094  15,880
APR       67,469  56,321    12,196  13,092
MAY       60,092  49,534    13,385  16,497
JUN       67,026  56,950    14,009  15,728
JUL       66,353  61,110    13,768  16,879
AUG       50,660  42,745    10,673  12,102
SEP       24,507  25,047     6,826   6,298
OCT       34,025  34,462    10,351   9,398
NOV       44,500     NaN     9,635     NaN
DEC       58,735     NaN    12,661     NaN

我们的目标是将此DataFrame转换为一个具有两行(分别代表“St Thomas”和“St. Croix”)和24列(例如“JAN2022”、“FEB2022”等)的结构。

核心重塑操作

为了实现上述目标,我们将利用Pandas的stack()、transpose()(或其简写.T)以及Index.map()方法。

1. 使用 stack() 堆叠最内层列索引

DataFrame.stack()方法用于将DataFrame的“宽”格式转换为“长”格式。它将DataFrame的列(或指定级别)“堆叠”到行索引上,从而产生一个Series或一个具有MultiIndex行的新DataFrame。

在这个例子中,我们的列索引是('Island', 'Year')的多级索引。默认情况下,stack()会堆叠最内层(即Year)的列索引。执行df.stack()后,Year级别将从列索引移动到行索引,与原有的Month索引形成一个MultiIndex行。

# 假设df是上面描述的初始DataFrame
# df = ... (通过前置代码生成)

# 堆叠最内层列索引 'Year'
stacked_df = df.stack()
print("--- After stack() ---")
print(stacked_df)

此时,stacked_df的结构将是:

Island         St Thomas St. Croix
Month Year                        
JAN   2022        55,086    11,550
      2023        60,470    12,755
FEB   2022        57,929    12,441
      2023        56,826    13,289
...
DEC   2022        58,735    12,661

现在,Month和Year是行索引,而Island是列索引。

2. 使用 transpose() 转置DataFrame

DataFrame.transpose()(或简写.T)方法用于交换DataFrame的行和列。在我们的场景中,我们希望Island成为行索引,而Month和Year的组合成为列索引。

对stacked_df执行转置操作:

transposed_df = stacked_df.T
print("\n--- After transpose() ---")
print(transposed_df)

转置后的transposed_df将具有以下结构:

Month     JAN            FEB            MAR       ... NOV     DEC    
Year     2022    2023   2022    2023   2022    2023 ... 2022    2022   
Island                                            ...                
St Thomas  55,086  60,470  57,929  56,826  72,103  64,249 ...  44,500  58,735
St. Croix  11,550  12,755  12,441  13,289  14,094  15,880 ...   9,635  12,661

现在,Island成为了行索引,而列索引是Month和Year组成的多级索引。这已经非常接近我们的目标了。

3. 使用 Index.map() 扁平化和自定义列名

最后一步是将多级列索引('Month', 'Year')扁平化为单个字符串,例如“JAN2022”。我们可以通过Index.map()方法,结合一个lambda函数来实现这一点。

Index.map()允许我们对索引中的每个元素应用一个函数,并返回一个新的索引。对于一个MultiIndex,每个元素是一个元组(例如 ('JAN', '2022'))。

# 扁平化列索引
transposed_df.columns = transposed_df.columns.map(lambda x: f'{x[0]}{x[1]}')

# 或者使用更简洁的方式
# transposed_df.columns = map(''.join, transposed_df.columns)

out = transposed_df
print("\n--- Final Output ---")
print(out)

最终输出的DataFrame out 将符合我们的要求:

          JAN2022 JAN2023 FEB2022 FEB2023 MAR2022 MAR2023 APR2022 APR2023 MAY2022 MAY2023 JUN2022 JUN2023 JUL2022 JUL2023 AUG2022 AUG2023 SEP2022 SEP2023 OCT2022 OCT2023 NOV2022 DEC2022
Island                                                                                                                                                                                   
St Thomas  55,086  60,470  57,929  56,826  72,103  64,249  67,469  56,321  60,092  49,534  67,026  56,950  66,353  61,110  50,660  42,745  24,507  25,047  34,025  34,462  44,500  58,735
St. Croix  11,550  12,755  12,441  13,289  14,094  15,880  12,196  13,092  13,385  16,497  14,009  15,728  13,768  16,879  10,673  12,102   6,826   6,298  10,351   9,398   9,635  12,661

完整代码示例

为了演示的完整性,下面提供了生成初始DataFrame并执行重塑操作的完整代码:

import pandas as pd
import tabula

# --- 原始DataFrame的生成代码 (来自问题描述) ---
page_number = "1"
pdf_url = "https://usviber.org/wp-content/uploads/2023/12/A23-OCT.pdf"

tables = tabula.read_pdf(pdf_url, pages=page_number)
df = tables[1]

numeric_columns = df.select_dtypes(include=["number"])
df = df.drop(numeric_columns.columns[(numeric_columns < 0).any()], axis=1)
df = df.loc[2:13, :].iloc[:, :5]

df.set_index(df.columns[0], inplace=True)

df.columns = pd.MultiIndex.from_product(
    [["St Thomas", "St. Croix"], ["2022", "2023"]], names=["Island", "Year"]
)

df.index = df.index.map(lambda x: str(x).upper()[:3])
df.index.set_names("Month", inplace=True)

print("--- Initial DataFrame ---")
print(df)

# --- 重塑操作 ---
# 1. 堆叠最内层列索引 'Year'
stacked_df = df.stack()

# 2. 转置DataFrame,使'Island'成为行索引
transposed_df = stacked_df.T

# 3. 扁平化多级列索引,合并'Month'和'Year'
transposed_df.columns = transposed_df.columns.map(lambda x: f'{x[0]}{x[1]}')

# 最终结果
out = transposed_df
print("\n--- Final Reshaped DataFrame ---")
print(out)

注意事项与总结

  • stack() 的层级控制:stack() 默认会堆叠最内层的列索引。如果需要堆叠特定层级的列索引,可以使用 stack(level=...) 参数。
  • unstack() 的反向操作:unstack() 是 stack() 的逆操作,它将行索引的某个级别转换为列索引。
  • 处理 NaN 值:在重塑过程中,如果原始数据包含 NaN 值,这些 NaN 值会保留在重塑后的DataFrame中。在某些情况下,你可能需要在重塑前后进行缺失值处理(例如填充、删除)。
  • 索引命名:在整个过程中,保持索引和列的良好命名习惯(通过 set_names())有助于代码的可读性和可维护性。
  • 灵活性:stack(), transpose(), unstack(), pivot_table(), melt() 等Pandas函数提供了强大的数据重塑能力,理解它们的工作原理对于高效处理复杂数据结构至关重要。

通过结合使用 stack()、transpose() 和 Index.map(),我们可以灵活地将复杂的MultiIndex DataFrame重塑为满足特定分析和展示需求的结构。这种方法在处理时间序列数据、交叉表格数据或需要改变数据透视角度时尤其有用。

本篇关于《Pandas多级列转行索引技巧》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于文章的相关知识,请关注golang学习网公众号!

Python环境搭建详细教程Python环境搭建详细教程
上一篇
Python环境搭建详细教程
PHPAPI文件下载及接口开发教程
下一篇
PHPAPI文件下载及接口开发教程
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • ChatExcel酷表:告别Excel难题,北大团队AI助手助您轻松处理数据
    ChatExcel酷表
    ChatExcel酷表是由北京大学团队打造的Excel聊天机器人,用自然语言操控表格,简化数据处理,告别繁琐操作,提升工作效率!适用于学生、上班族及政府人员。
    3182次使用
  • Any绘本:开源免费AI绘本创作工具深度解析
    Any绘本
    探索Any绘本(anypicturebook.com/zh),一款开源免费的AI绘本创作工具,基于Google Gemini与Flux AI模型,让您轻松创作个性化绘本。适用于家庭、教育、创作等多种场景,零门槛,高自由度,技术透明,本地可控。
    3393次使用
  • 可赞AI:AI驱动办公可视化智能工具,一键高效生成文档图表脑图
    可赞AI
    可赞AI,AI驱动的办公可视化智能工具,助您轻松实现文本与可视化元素高效转化。无论是智能文档生成、多格式文本解析,还是一键生成专业图表、脑图、知识卡片,可赞AI都能让信息处理更清晰高效。覆盖数据汇报、会议纪要、内容营销等全场景,大幅提升办公效率,降低专业门槛,是您提升工作效率的得力助手。
    3425次使用
  • 星月写作:AI网文创作神器,助力爆款小说速成
    星月写作
    星月写作是国内首款聚焦中文网络小说创作的AI辅助工具,解决网文作者从构思到变现的全流程痛点。AI扫榜、专属模板、全链路适配,助力新人快速上手,资深作者效率倍增。
    4530次使用
  • MagicLight.ai:叙事驱动AI动画视频创作平台 | 高效生成专业级故事动画
    MagicLight
    MagicLight.ai是全球首款叙事驱动型AI动画视频创作平台,专注于解决从故事想法到完整动画的全流程痛点。它通过自研AI模型,保障角色、风格、场景高度一致性,让零动画经验者也能高效产出专业级叙事内容。广泛适用于独立创作者、动画工作室、教育机构及企业营销,助您轻松实现创意落地与商业化。
    3802次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码