
本教程详细介绍了如何将一个具有大量列的宽格式Pandas DataFrame重塑为更易读的垂直长格式。文章提供了两种核心方法:当总列数是目标列数的完美倍数时,可以使用NumPy的`reshape`功能高效处理;当总列数不是目标列数的完美倍数时,则采用Pandas的`MultiIndex`和`stack`操作灵活应对。通过具体代码示例和注意事项,帮助读者掌握数据重塑技巧,提升数据处理效率和可读性。
在数据分析和处理中,我们经常会遇到包含大量列的“宽格式”DataFrame。这种格式在某些情况下可能难以阅读和分析,例如,当逻辑上相关的列被水平地分散在整个数据集中时。本教程将指导您如何将这类宽格式DataFrame,按照每N列一组的方式,重塑为一个更紧凑、更易于理解的“长格式”DataFrame。我们将探讨两种主要场景:当总列数是目标分组列数的完美倍数时,以及当它不是完美倍数时。
当原始DataFrame的总列数能够被目标分组列数(例如,每6列一组)整除时,使用NumPy的reshape功能是最高效且简洁的方法。
这种方法的核心是将DataFrame转换为NumPy数组,然后利用numpy.reshape()将其重塑为新的维度。由于我们希望最终的DataFrame有固定数量的列(例如6列),我们可以指定目标列数为6,并让NumPy自动推断行数。
假设我们有一个包含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的倍数,此方法不适用。")
代码解析:
输出示例:
原始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的总列数不能被目标分组列数整除时(例如,有5252列,但我们仍想每6列一组),numpy.reshape将无法直接使用。此时,我们可以利用Pandas的MultiIndex和stack操作来灵活处理。
这种方法通过创建一个多级列索引来逻辑地分组原始列,然后使用stack()方法将这些分组转换为行。对于不完整的最后一组,stack()会自动填充NaN。
假设我们有一个包含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)代码解析:
输出示例:
原始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
注意事项:
本教程介绍了两种将宽格式DataFrame重塑为长格式的有效方法:
选择哪种方法取决于您的具体数据特性和需求。在实际应用中,了解这两种方法可以帮助您更高效、更灵活地处理各种数据重塑任务。始终记住在重塑后检查数据类型和NaN值,以确保数据质量符合后续分析要求。
以上就是如何将宽格式DataFrame按固定列数重塑为长格式的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号