Pandas DataFrame多层索引重塑:将列索引与行索引合并为新列名

DDD
发布: 2025-11-07 11:23:01
原创
193人浏览过

pandas dataframe多层索引重塑:将列索引与行索引合并为新列名

本文详细介绍了如何使用Pandas库对具有多层列索引的DataFrame进行高效重塑。通过结合`stack()`、`transpose()`和`Index.map()`等核心函数,我们将演示如何将DataFrame的最低层列索引与原始行索引合并,生成新的扁平化列名,同时将原高层列索引转换为新的行索引,从而实现数据从宽到长的灵活转换。

在数据分析和处理中,我们经常需要根据特定的分析需求调整DataFrame的结构。当DataFrame包含多层列索引时,这种重塑操作可能显得复杂。本教程将以一个具体的案例为例,详细讲解如何将DataFrame的多层列索引中的特定层与行索引合并,创建新的扁平化列名,并将原始的高层列索引转换为新的行索引,最终得到一个更适合特定分析场景的二维表格。

初始DataFrame结构

假设我们有一个从PDF文件中提取并经过预处理的Pandas DataFrame,其结构如下所示。这个DataFrame的列是多层索引(MultiIndex),包含“Island”(岛屿)和“Year”(年份)两层,行索引是“Month”(月份)。

import pandas as pd
import tabula

# 示例数据加载与预处理(与原始问题保持一致)
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("原始DataFrame:")
print(df)
登录后复制

原始DataFrame的输出结构如下:

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
登录后复制

我们的目标是将“Island”(岛屿)作为新的行索引,并将“Month”(月份)与“Year”(年份)拼接成新的列名(例如“JAN2022”、“FEB2022”),最终得到一个2行24列的DataFrame。

重塑DataFrame的步骤

为了实现上述目标,我们将分三步进行操作:

1. 使用 stack() 转换列索引层级

stack() 函数用于将DataFrame的“列”转换为“行”。默认情况下,它会将DataFrame最内层的列索引(即Year)转换为新的行索引层级。这使得原始的Month和Year共同构成了新的行MultiIndex。

# 将最内层列索引 (Year) 堆叠到行索引
stacked_df = df.stack()
print("\n堆叠后的DataFrame (stacked_df):")
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
登录后复制

此时,stacked_df 的列索引是 Island,行索引是 Month 和 Year 的 MultiIndex。

纳米搜索
纳米搜索

纳米搜索:360推出的新一代AI搜索引擎

纳米搜索 30
查看详情 纳米搜索

2. 使用 transpose() (或 .T) 转置DataFrame

在stack()操作之后,我们希望将Island从列转换为行,并将Month和Year的组合作为新的列。这时,使用transpose()方法(或其简写.T)可以实现行与列的互换。

# 转置DataFrame
out = stacked_df.T
print("\n转置后的DataFrame (out):")
print(out)
登录后复制

out 的输出将是:

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

现在,Island 已经成为了行索引,而列索引则变成了 Month 和 Year 的 MultiIndex。

3. 扁平化列MultiIndex

最后一步是将列索引中的Month和Year组合成单个字符串,例如“JAN2022”。我们可以通过对列索引应用 map() 函数来实现这一点。

# 扁平化列MultiIndex,将月份和年份拼接
out.columns = out.columns.map(lambda x: f'{x[0]}{x[1]}')

# 或者,对于简单的字符串拼接,也可以使用 map(''.join, out.columns)
# out.columns = map(''.join, out.columns)

print("\n最终重塑后的DataFrame:")
print(out)
登录后复制

最终输出的DataFrame将符合我们的预期:

          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
登录后复制

完整代码示例

将上述步骤整合到一起,完整的代码如下:

import pandas as pd
import tabula

# 1. 初始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)

# 2. 重塑操作
# 步骤1: 堆叠最内层列索引 (Year) 到行索引
stacked_df = df.stack()

# 步骤2: 转置DataFrame,使 'Island' 成为行索引,'Month'/'Year' 成为列MultiIndex
out = stacked_df.T

# 步骤3: 扁平化列MultiIndex,将月份和年份拼接
out.columns = out.columns.map(lambda x: f'{x[0]}{x[1]}')

print("\n最终重塑后的DataFrame:")
print(out)
登录后复制

注意事项与总结

  • stack() 的灵活性:stack() 默认会将最内层的列索引堆叠,但你可以通过 level 参数指定要堆叠的列索引层级。
  • transpose() 的应用:.T 是 transpose() 的便捷方式,用于快速交换DataFrame的行和列。
  • Index.map() 的强大功能:map() 方法不仅可以用于Series,也可以用于Index对象,对索引的每个元素应用一个函数,非常适合进行格式化或组合操作。
  • 数据类型:在拼接列名时,确保索引中的元素是字符串类型或可转换为字符串的类型。f'{x[0]}{x[1]}' 这种f-string格式化方法非常灵活,可以处理不同类型的数据。
  • NaN 值处理:在重塑过程中,如果原始数据中存在 NaN 值,它们会自然地保留在重塑后的DataFrame中。在某些情况下,你可能需要在重塑前后进行 fillna() 或 dropna() 操作。

通过掌握 stack()、transpose() 和 Index.map() 这三个Pandas核心函数,你可以高效地处理复杂的DataFrame重塑任务,将数据转换成最适合你分析需求的结构。这种方法在处理时间序列数据、面板数据或需要交叉分析多维度数据时尤其有用。

以上就是Pandas DataFrame多层索引重塑:将列索引与行索引合并为新列名的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号