将宽格式DataFrame重塑为垂直结构:Pandas与NumPy的实践指南

碧海醫心
发布: 2025-10-25 14:36:01
原创
401人浏览过

将宽格式DataFrame重塑为垂直结构:Pandas与NumPy的实践指南

在数据分析中,我们经常遇到水平宽度过大的dataframe,这不仅降低了可读性,也阻碍了后续的数据处理。本教程将详细介绍如何将这类宽格式dataframe转换为更易于分析的垂直结构,特别是当我们需要将每n列提取并作为行追加到新的dataframe时。我们将探讨两种主要方法:利用numpy的`reshape`功能处理列数为n的倍数的情况,以及使用pandas的`multiindex`和`stack`功能处理更通用的情况。

数据重塑:从宽到长的转换

在处理大规模数据集时,原始数据往往以宽格式呈现,即包含数百甚至数千列。这种格式对于某些数据源是自然的,但对于多数分析任务来说,将其转换为“长”或“垂直”格式更为合适。例如,一个包含多组重复测量数据的DataFrame,每组数据占据6列,我们希望将其转换为每行代表一组完整测量的新DataFrame。

假设我们有一个名为 groups.csv 的CSV文件,加载后得到一个具有606列的Pandas DataFrame。我们的目标是每6列一组,将这些数据转换为一个拥有指定6列(例如'GroupA'到'GroupF')的新DataFrame,每一行代表原始DataFrame中的一组数据。

import pandas as pd
import numpy as np

# 模拟一个宽格式DataFrame
# 实际应用中,你会从CSV文件加载
# df = pd.read_csv("groups.csv")

# 示例数据:3行12列,每6列为一组
np.random.seed(123)
df = pd.DataFrame(np.random.randint(10, size=(3, 12)))
print("原始DataFrame:")
print(df)
登录后复制

输出:

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

方法一:使用NumPy的reshape功能(适用于列数是N的倍数)

当原始DataFrame的列数恰好是目标组大小(例如6)的倍数时,NumPy的reshape方法提供了一种高效且简洁的解决方案。

原理

  1. 转换为NumPy数组:Pandas DataFrame底层数据通常是NumPy数组,通过.to_numpy()方法可以获取。
  2. 重塑数组:numpy.reshape(new_shape)允许我们改变数组的维度。关键在于new_shape的定义。如果我们将目标列数设为6,而行数未知,可以使用-1让NumPy自动计算。例如,reshape(-1, 6)会将数组重塑为任意行数、6列的二维数组。
  3. 创建新DataFrame:将重塑后的NumPy数组传递给pd.DataFrame,并指定新的列名。

实现步骤

首先,确认原始DataFrame的列数是否是目标组大小的倍数。

# 假设目标是每6列为一组
target_cols_per_group = 6
total_columns = len(df.columns)

print(f"原始DataFrame总列数: {total_columns}")
print(f"总列数 % {target_cols_per_group} = {total_columns % target_cols_per_group}")

if total_columns % target_cols_per_group == 0:
    print("列数是目标组大小的倍数,可以使用NumPy的reshape方法。")
else:
    print("列数不是目标组大小的倍数,需要使用更通用的Pandas方法。")
登录后复制

如果列数是倍数,我们可以直接应用reshape:

吉卜力风格图片在线生成
吉卜力风格图片在线生成

将图片转换为吉卜力艺术风格的作品

吉卜力风格图片在线生成121
查看详情 吉卜力风格图片在线生成
# 定义新DataFrame的列名
new_columns = ['GroupA', 'GroupB', 'GroupC', 'GroupD', 'GroupE', 'GroupF']

# 将DataFrame转换为NumPy数组,然后重塑
# df.to_numpy().reshape(-1, target_cols_per_group) 会将所有数据展平后按6列重新组织
# 但这里我们希望保持原始行结构,即每行的数据作为一个整体被重新组织
# 正确的做法是先将整个DataFrame展平,再进行重塑
# 错误的理解可能导致:df.to_numpy().reshape(len(df) * (total_columns // target_cols_per_group), target_cols_per_group)
# 实际上,`df.to_numpy()`会返回一个 (rows, cols) 的数组
# 如果我们想把 (3, 12) 变成 (6, 6),我们需要先展平为 (36,),再重塑为 (6, 6)
# 或者更直接地,将整个DataFrame的数据视为一个整体进行重塑
df_target_numpy = pd.DataFrame(df.to_numpy().reshape(-1, target_cols_per_group),
                               columns=new_columns)
print("\n使用NumPy reshape重塑后的DataFrame:")
print(df_target_numpy)
登录后复制

输出:

使用NumPy reshape重塑后的DataFrame:
   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的总列数必须是目标组大小的精确倍数。如果不是,reshape会报错,或者产生非预期的结果。
  • df.to_numpy()会丢弃DataFrame的列名,因此我们需要在创建新DataFrame时手动指定列名。
  • 此方法处理的是DataFrame的,而不是其索引或列名。

方法二:使用Pandas MultiIndex和stack功能(适用于更通用的情况)

当原始DataFrame的列数不是目标组大小的精确倍数时,或者需要更灵活地处理列名时,Pandas的MultiIndex和stack组合提供了强大的功能。这种方法可以优雅地处理列数不匹配的情况,并自动填充NaN值。

原理

  1. 创建多级索引:利用整数除法//和取模运算%,为原始列创建两级索引。
    • a // 6:确定每个组的索引(例如,0-5列属于第0组,6-11列属于第1组)。
    • a % 6:确定组内元素的索引(0到5)。
  2. 设置新轴:使用df.set_axis([level0_index, level1_index], axis=1)将这些多级索引应用到列轴。
  3. 堆叠数据:stack()方法会将DataFrame的列“堆叠”到行上,将最内层的列索引转换为行索引的一部分。这正是我们将宽数据转换为长数据所需的关键步骤。
  4. 重命名列:堆叠后,列名会丢失,需要重新指定。
  5. 重置索引:reset_index(drop=True)清理新生成的索引。

实现步骤

# 示例数据:3行10列,每6列为一组,但10不是6的倍数
np.random.seed(123)
df_uneven = pd.DataFrame(np.random.randint(10, size=(3, 10)))
print("\n原始DataFrame (列数非倍数):")
print(df_uneven)

total_columns_uneven = len(df_uneven.columns)
print(f"原始DataFrame总列数: {total_columns_uneven}")
print(f"总列数 % {target_cols_per_group} = {total_columns_uneven % target_cols_per_group}")

# 为列创建多级索引
# level0_index: 0, 0, 0, 0, 0, 0, 1, 1, 1, 1 (表示第几组)
# level1_index: 0, 1, 2, 3, 4, 5, 0, 1, 2, 3 (表示组内第几列)
a = np.arange(total_columns_uneven)
multi_index_level0 = a // target_cols_per_group # 组索引
multi_index_level1 = a % target_cols_per_group  # 组内列索引

# 设置多级列索引
df_multi_indexed = df_uneven.set_axis([multi_index_level1, multi_index_level0], axis=1)
print("\n设置多级索引后的DataFrame:")
print(df_multi_indexed)

# 堆叠数据
# stack()默认会堆叠最内层的列索引(即multi_index_level1)
df_stacked = df_multi_indexed.stack()
print("\n堆叠后的DataFrame:")
print(df_stacked)

# 重命名列并重置索引
df_target_pandas = df_stacked.set_axis(new_columns, axis=1).reset_index(drop=True)
print("\n使用Pandas MultiIndex和stack重塑后的DataFrame:")
print(df_target_pandas)
登录后复制

输出:

原始DataFrame (列数非倍数):
   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:
   0  1  2  3  4  5  0  1  2  3
   0  0  0  0  0  0  1  1  1  1
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:
      0  1  2  3  4  5
0 0   2  2  6  1  3  9
  1   6  1  0  1  9  0
1 0   0  9  3  4  0  0
  1   4  1  7  3  2  4
2 0   7  3  2  4  7  2
  1   4  8  0  7  NaN  NaN

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

注意事项

  • 当原始列数不是目标组大小的倍数时,stack()操作会在不足的列位置自动填充NaN。这通常是期望的行为,但需要注意后续处理中对NaN值的处理。
  • 这种方法比NumPy reshape更灵活,因为它利用了Pandas的索引和重塑功能,能够更好地处理非规则数据。
  • 性能上,对于非常大的数据集,numpy.reshape可能略快,但Pandas方法在处理复杂情况时提供了更高的鲁棒性和可读性。

总结与选择

将宽格式DataFrame重塑为垂直结构是数据清理和准备的关键步骤。本教程介绍了两种有效的方法:

  1. NumPy reshape:适用于原始DataFrame列数是目标组大小的精确倍数的情况。它简洁高效,但对输入数据结构有严格要求。
  2. Pandas MultiIndex和stack:适用于更通用的场景,包括列数不是目标组大小倍数的情况。它通过引入NaN值来处理不完整的数据组,提供了更大的灵活性和鲁棒性。

在实际应用中,应根据你的数据特点和具体需求选择最合适的方法。如果数据总是规整的,reshape是一个不错的选择;如果数据可能不规整,或者需要更细致的控制,Pandas的MultiIndex和stack组合将是更强大的工具。无论选择哪种方法,目标都是为了获得一个结构清晰、易于分析的DataFrame。

以上就是将宽格式DataFrame重塑为垂直结构:Pandas与NumPy的实践指南的详细内容,更多请关注php中文网其它相关文章!

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

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

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

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