
本文详细介绍了如何使用Pandas库对具有多层列索引的DataFrame进行高效重塑。通过结合`stack()`、`transpose()`和`Index.map()`等核心函数,我们将演示如何将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。
为了实现上述目标,我们将分三步进行操作:
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。
在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。
最后一步是将列索引中的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()、transpose() 和 Index.map() 这三个Pandas核心函数,你可以高效地处理复杂的DataFrame重塑任务,将数据转换成最适合你分析需求的结构。这种方法在处理时间序列数据、面板数据或需要交叉分析多维度数据时尤其有用。
以上就是Pandas DataFrame多层索引重塑:将列索引与行索引合并为新列名的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号