
本文详细介绍了如何将宽格式的pandas dataframe重塑为更易读的垂直长表,特别是当需要每n列作为一个逻辑组进行处理时。文章提供了两种核心方法:当总列数是n的倍数时,可高效利用`numpy.reshape`进行批量转换;而对于总列数不是n的倍数的情况,则通过pandas的`multiindex`和`stack`功能实现灵活重塑,并处理可能出现的缺失值。
在数据分析和处理中,我们经常会遇到宽格式的数据集,其中包含大量水平排列的列。为了便于分析或满足特定需求(例如,将每N列视为一个逻辑单元并将其堆叠成新的行),我们需要将这种宽表结构重塑为更垂直、更规范的长表。本文将详细介绍两种在Pandas中实现这一目标的方法。
假设我们有一个非常宽的CSV文件,例如包含606列,我们已将其导入到Pandas DataFrame中。我们的目标是将原始DataFrame中每6列提取出来,作为一个新的逻辑组,并将其堆叠到目标DataFrame的行中。目标DataFrame应具有预定义的列名,例如['GroupA', 'GroupB', 'GroupC', 'GroupD', 'GroupE', 'GroupF']。
当原始DataFrame的总列数是目标组列数(N)的整数倍时,numpy.reshape提供了一种非常高效且简洁的解决方案。这种方法将整个DataFrame的数据扁平化为一个一维数组,然后按照新的行数和列数进行重塑。
假设我们有一个3行12列的DataFrame,需要将其重塑为每6列一组。
import pandas as pd
import numpy as np
# 模拟一个宽格式的DataFrame
np.random.seed(123)
df_wide = pd.DataFrame(np.random.randint(10, size=(3, 12)))
print("原始宽格式DataFrame:")
print(df_wide)
# 输出:
# 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
# 检查列数是否是目标列数N的倍数
N = 6
if len(df_wide.columns) % N != 0:
print(f"警告:原始列数 {len(df_wide.columns)} 不是 {N} 的整数倍,此方法可能不适用或需调整。")
else:
print(f"\n原始DataFrame列数: {len(df_wide.columns)}")
print(f"列数 {len(df_wide.columns)} 是 {N} 的整数倍: {len(df_wide.columns) % N == 0}")
# 定义目标DataFrame的列名
target_columns = ['GroupA', 'GroupB', 'GroupC', 'GroupD', 'GroupE', 'GroupF']
# 使用numpy.reshape进行重塑
df_target = pd.DataFrame(df_wide.to_numpy().reshape(-1, N),
columns=target_columns)
print("\n重塑后的目标DataFrame:")
print(df_target)
# 输出:
# 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的列数不是目标组列数N的整数倍时,或者当我们需要更灵活地处理列名和分组逻辑时,Pandas的MultiIndex结合stack方法提供了更通用的解决方案。这种方法通过创建多级列索引来标记每个列所属的组和其在组内的位置,然后利用stack将这些组堆叠起来。
假设我们有一个3行10列的DataFrame,需要将其重塑为每6列一组。由于10不是6的倍数,部分行将包含NaN。
import pandas as pd
import numpy as np
# 模拟一个宽格式的DataFrame,列数不是6的倍数
np.random.seed(123)
df_wide_uneven = pd.DataFrame(np.random.randint(10, size=(3, 10)))
print("原始宽格式DataFrame (列数非倍数):")
print(df_wide_uneven)
# 输出:
# 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
N = 6
print(f"\n原始DataFrame列数: {len(df_wide_uneven.columns)}")
print(f"列数 {len(df_wide_uneven.columns)} 是 {N} 的整数倍: {len(df_wide_uneven.columns) % N == 0}")
# 定义目标DataFrame的列名
target_columns = ['GroupA', 'GroupB', 'GroupC', 'GroupD', 'GroupE', 'GroupF']
# 创建列索引数组
a = np.arange(len(df_wide_uneven.columns))
# 构建MultiIndex并堆叠
df_target_uneven = (df_wide_uneven.set_axis([a % N, a // N], axis=1) # 创建MultiIndex: (列内序号, 组号)
.stack() # 堆叠最内层索引 (组号)
.set_axis(target_columns, axis=1) # 重命名列
.reset_index(drop=True)) # 重置索引
print("\n重塑后的目标DataFrame (处理非倍数列数):")
print(df_target_uneven)
# 输出:
# 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将宽格式的Pandas DataFrame重塑为按固定列数分组的长表是数据清洗和预处理的常见任务。
选择哪种方法取决于你的具体数据结构和对效率、灵活性以及缺失值处理的需求。理解这两种方法的原理和适用场景,能够帮助你更有效地处理各种数据重塑任务。
以上就是Pandas DataFrame宽表重塑:按固定列数分组并堆叠为长表的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号