0

0

如何将宽格式DataFrame按固定列数重塑为长格式

心靈之曲

心靈之曲

发布时间:2025-10-25 09:17:37

|

250人浏览过

|

来源于php中文网

原创

如何将宽格式dataframe按固定列数重塑为长格式

本教程详细介绍了如何将一个具有大量列的宽格式Pandas DataFrame重塑为更易读的垂直长格式。文章提供了两种核心方法:当总列数是目标列数的完美倍数时,可以使用NumPy的`reshape`功能高效处理;当总列数不是目标列数的完美倍数时,则采用Pandas的`MultiIndex`和`stack`操作灵活应对。通过具体代码示例和注意事项,帮助读者掌握数据重塑技巧,提升数据处理效率和可读性。

数据重塑:将宽格式DataFrame转换为长格式

在数据分析和处理中,我们经常会遇到包含大量列的“宽格式”DataFrame。这种格式在某些情况下可能难以阅读和分析,例如,当逻辑上相关的列被水平地分散在整个数据集中时。本教程将指导您如何将这类宽格式DataFrame,按照每N列一组的方式,重塑为一个更紧凑、更易于理解的“长格式”DataFrame。我们将探讨两种主要场景:当总列数是目标分组列数的完美倍数时,以及当它不是完美倍数时。

场景一:总列数是目标分组列数的完美倍数

当原始DataFrame的总列数能够被目标分组列数(例如,每6列一组)整除时,使用NumPy的reshape功能是最高效且简洁的方法。

1.1 方法概述

这种方法的核心是将DataFrame转换为NumPy数组,然后利用numpy.reshape()将其重塑为新的维度。由于我们希望最终的DataFrame有固定数量的列(例如6列),我们可以指定目标列数为6,并让NumPy自动推断行数。

1.2 示例代码

假设我们有一个包含606列的DataFrame,并且我们希望每6列为一组,将其转换为一个具有6列的新DataFrame。

import pandas as pd
import numpy as np

# 模拟一个宽格式DataFrame
# 实际应用中,这里会是 df = pd.read_csv("groups.csv")
np.random.seed(123)
# 假设原始DataFrame有3行12列,每6列一组,目标DataFrame有6列
df = pd.DataFrame(np.random.randint(10, size=(3, 12)))
print("原始DataFrame:")
print(df)
# 预期输出列名
target_columns = ['GroupA', 'GroupB', 'GroupC', 'GroupD', 'GroupE', 'GroupF']

# 检查总列数是否为目标分组列数的倍数
print(f"\n原始DataFrame列数: {len(df.columns)}")
print(f"列数 % 6: {len(df.columns) % 6}")

if len(df.columns) % 6 == 0:
    # 将DataFrame转换为NumPy数组,然后重塑
    # -1 表示让NumPy自动计算行数,6 表示目标DataFrame的列数
    df_target = pd.DataFrame(df.to_numpy().reshape(-1, 6),
                             columns=target_columns)
    print("\n重塑后的DataFrame (使用 numpy.reshape):")
    print(df_target)
else:
    print("\n原始DataFrame的列数不是6的倍数,此方法不适用。")

代码解析:

  1. df.to_numpy(): 将Pandas DataFrame转换为底层的NumPy数组。这会移除列名,只保留数据值。
  2. .reshape(-1, 6): 这是关键步骤。它将NumPy数组重塑为一个新的形状。
    • -1: 告诉NumPy根据数组中的元素总数和指定的其他维度(这里是6列)自动计算新的行数。
    • 6: 指定新DataFrame的列数。
  3. pd.DataFrame(..., columns=target_columns): 将重塑后的NumPy数组转换回Pandas DataFrame,并指定新的列名。

输出示例:

原始DataFrame:
   0  1  2  3  4  5  6  7  8  9  10  11
0  2  2  6  1  3  9  6  1  0  1   9   0
1  0  9  3  4  0  0  4  1  7  3   2   4
2  7  2  4  8  0  7  9  3  4  6   1   5

原始DataFrame列数: 12
列数 % 6: 0

重塑后的DataFrame (使用 numpy.reshape):
   GroupA  GroupB  GroupC  GroupD  GroupE  GroupF
0       2       2       6       1       3       9
1       6       1       0       1       9       0
2       0       9       3       4       0       0
3       4       1       7       3       2       4
4       7       2       4       8       0       7
5       9       3       4       6       1       5

注意事项:

  • 此方法要求原始DataFrame的所有数据类型都是兼容的,因为NumPy数组通常是同构的。如果DataFrame包含混合数据类型,to_numpy()可能会将其转换为object类型。
  • 此方法不保留原始的行索引信息,如果需要,需在重塑前进行保存或后续处理。

场景二:总列数不是目标分组列数的完美倍数

当原始DataFrame的总列数不能被目标分组列数整除时(例如,有5252列,但我们仍想每6列一组),numpy.reshape将无法直接使用。此时,我们可以利用Pandas的MultiIndex和stack操作来灵活处理。

Build AI
Build AI

为您的业务构建自己的AI应用程序。不需要任何技术技能。

下载

2.1 方法概述

这种方法通过创建一个多级列索引来逻辑地分组原始列,然后使用stack()方法将这些分组转换为行。对于不完整的最后一组,stack()会自动填充NaN。

2.2 示例代码

假设我们有一个包含10列的DataFrame,但我们仍然希望每6列为一组进行重塑。

import pandas as pd
import numpy as np

# 模拟一个宽格式DataFrame
np.random.seed(123)
# 假设原始DataFrame有3行10列,每6列一组,目标DataFrame有6列
df_imperfect = pd.DataFrame(np.random.randint(10, size=(3, 10)))
print("原始DataFrame (列数非6的倍数):")
print(df_imperfect)

# 预期输出列名
target_columns = ['GroupA', 'GroupB', 'GroupC', 'GroupD', 'GroupE', 'GroupF']
group_size = 6

print(f"\n原始DataFrame列数: {len(df_imperfect.columns)}")
print(f"列数 % {group_size}: {len(df_imperfect.columns) % group_size}")

# 创建一个用于生成MultiIndex的数组
a = np.arange(len(df_imperfect.columns))

# 使用 set_axis 和 MultiIndex 进行重塑
# a % group_size: 生成第一级索引,表示组内位置 (0到5)
# a // group_size: 生成第二级索引,表示是第几组 (0, 1, ...)
df_target_imperfect = (df_imperfect.set_axis([a % group_size, a // group_size], axis=1)
                                   .stack(level=0) # 将第一级索引(组内位置)堆叠为行
                                   .set_axis(target_columns, axis=1) # 设置新的列名
                                   .reset_index(drop=True)) # 重置索引,移除MultiIndex的层级
print("\n重塑后的DataFrame (使用 Pandas MultiIndex 和 stack):")
print(df_target_imperfect)

代码解析:

  1. a = np.arange(len(df_imperfect.columns)): 创建一个与列数等长的整数序列,用于生成索引。
  2. df_imperfect.set_axis([a % group_size, a // group_size], axis=1):
    • a % group_size: 计算每个原始列在目标组中的位置(0, 1, 2, 3, 4, 5, 0, 1, ...)。这将成为MultiIndex的第一层。
    • a // group_size: 计算每个原始列属于哪一个目标组(0, 0, 0, 0, 0, 0, 1, 1, ...)。这将成为MultiIndex的第二层。
    • set_axis(..., axis=1): 将生成的这两个数组作为新的列索引,创建多级列索引。
  3. .stack(level=0): 这是核心的重塑操作。它将MultiIndex的第一层(即组内位置)从列级别堆叠到行级别。这意味着每个原始行的数据,将根据其在组中的位置,被转换为多行。
  4. .set_axis(target_columns, axis=1): 堆叠后,列名会变成默认的数字索引,我们将其重新设置为目标列名。
  5. .reset_index(drop=True): stack()操作会引入新的索引层级。reset_index(drop=True)用于将这些层级移除,并生成一个干净的默认整数索引。

输出示例:

原始DataFrame (列数非6的倍数):
   0  1  2  3  4  5  6  7  8  9
0  2  2  6  1  3  9  6  1  0  1
1  9  0  0  9  3  4  0  0  4  1
2  7  3  2  4  7  2  4  8  0  7

原始DataFrame列数: 10
列数 % 6: 4

重塑后的DataFrame (使用 Pandas MultiIndex 和 stack):
   GroupA  GroupB  GroupC  GroupD  GroupE  GroupF
0       2       2       6       1     3.0     9.0
1       6       1       0       1     NaN     NaN
2       9       0       0       9     3.0     4.0
3       0       0       4       1     NaN     NaN
4       7       3       2       4     7.0     2.0
5       4       8       0       7     NaN     NaN

注意事项:

  • 当最后一组的列数不足group_size时,stack()会自动填充NaN值。您可能需要根据具体需求处理这些NaN值(例如,使用fillna()或dropna())。
  • 此方法比numpy.reshape更灵活,但对于非常大的数据集,性能可能会略低于纯NumPy方法。
  • 同样,原始行索引信息不会直接保留。

总结

本教程介绍了两种将宽格式DataFrame重塑为长格式的有效方法:

  1. numpy.reshape(-1, N): 适用于原始列数是目标分组列数N的完美倍数的情况。它直接操作底层NumPy数组,效率高,代码简洁。
  2. Pandas MultiIndex + stack(): 适用于原始列数不是目标分组列数N的完美倍数的情况。它利用Pandas强大的索引和重塑功能,能够灵活处理不完整的分组,并自动填充NaN。

选择哪种方法取决于您的具体数据特性和需求。在实际应用中,了解这两种方法可以帮助您更高效、更灵活地处理各种数据重塑任务。始终记住在重塑后检查数据类型和NaN值,以确保数据质量符合后续分析要求。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Python 时间序列分析与预测
Python 时间序列分析与预测

本专题专注讲解 Python 在时间序列数据处理与预测建模中的实战技巧,涵盖时间索引处理、周期性与趋势分解、平稳性检测、ARIMA/SARIMA 模型构建、预测误差评估,以及基于实际业务场景的时间序列项目实操,帮助学习者掌握从数据预处理到模型预测的完整时序分析能力。

71

2025.12.04

Python 数据清洗与预处理实战
Python 数据清洗与预处理实战

本专题系统讲解 Python 在数据清洗与预处理中的核心技术,包括使用 Pandas 进行缺失值处理、异常值检测、数据格式化、特征工程与数据转换,结合 NumPy 高效处理大规模数据。通过实战案例,帮助学习者掌握 如何处理混乱、不完整数据,为后续数据分析与机器学习模型训练打下坚实基础。

1

2026.01.31

数据类型有哪几种
数据类型有哪几种

数据类型有整型、浮点型、字符型、字符串型、布尔型、数组、结构体和枚举等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

310

2023.10.31

php数据类型
php数据类型

本专题整合了php数据类型相关内容,阅读专题下面的文章了解更多详细内容。

222

2025.10.31

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

398

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

575

2023.08.10

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

398

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

575

2023.08.10

2026赚钱平台入口大全
2026赚钱平台入口大全

2026年最新赚钱平台入口汇总,涵盖任务众包、内容创作、电商运营、技能变现等多类正规渠道,助你轻松开启副业增收之路。阅读专题下面的文章了解更多详细内容。

30

2026.01.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

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