0

0

将Pandas DataFrame中的多列堆叠重塑为规范化格式

心靈之曲

心靈之曲

发布时间:2025-11-24 13:43:27

|

305人浏览过

|

来源于php中文网

原创

将pandas dataframe中的多列堆叠重塑为规范化格式

本文旨在深入探讨如何利用Pandas库对DataFrame进行多列堆叠和重塑操作,以实现从宽格式到长格式的转换。我们将介绍三种主要方法:基于MultiIndex的自定义重塑、结合`melt`和`pivot`函数,以及使用`janitor`库中的`pivot_longer`功能。通过示例代码和详细解释,读者将掌握在处理具有特定命名模式(如`*_count`, `*_sum`)的列时,如何高效地将数据结构化,从而提升数据分析的灵活性和可读性。

在数据分析和处理中,我们经常会遇到需要将DataFrame从“宽”格式转换为“长”格式的场景。这种转换对于数据可视化、统计分析以及与特定工具集成至关重要。特别是当DataFrame中的列名遵循某种模式,例如side_metric(如left_count,right_sum),我们希望将这些模式分解,并将side和metric作为新的列。

考虑以下初始DataFrame,它包含日期、其他标识符以及左右两侧的计数和总和数据:

import pandas as pd

df = pd.DataFrame({
    'date': ['2023-12-01', '2023-12-05', '2023-12-07'],
    'other_col': ['a', 'b', 'c'],
    'right_count': [4, 7, 9],
    'right_sum': [2, 3, 5],
    'left_count': [1, 8, 5],
    'left_sum': [0, 8, 4]
})

print("原始DataFrame:")
print(df)

原始DataFrame结构如下:

         date other_col  right_count  right_sum  left_count  left_sum
0  2023-12-01         a            4          2           1         0
1  2023-12-05         b            7          3           8         8
2  2023-12-07         c            9          5           5         4

我们的目标是将其重塑为以下“长”格式,其中side列表示“left”或“right”,count和sum则作为单独的度量列:

         date other_col   side  count  sum
0  2023-12-01         a  right      4    2
1  2023-12-05         b  right      7    3
2  2023-12-07         c  right      9    5
3  2023-12-01         a   left      1    0
4  2023-12-05         b   left      8    8
5  2023-12-07         c   left      5    4

下面将介绍几种实现此目标的方法。

方法一:利用MultiIndex进行自定义重塑

这种方法通过创建临时的MultiIndex列来实现灵活的数据重塑,步骤相对复杂但非常灵活。

  1. 设置索引: 首先,将不需要堆叠的列(如date, other_col)设置为DataFrame的索引。
  2. 创建MultiIndex列: 使用columns.str.split('_', expand=True)将列名(如right_count)拆分为多级索引(right, count)。
  3. 重命名轴: rename_axis(columns=['side', None])为新的多级列索引的第一级命名为side,第二级保持匿名。
  4. 堆叠: stack('side')将名为side的列索引级别转换为行索引。
  5. 重置索引: reset_index()将所有索引级别转换回普通列。
out_multiindex = (df
    .set_index(['date', 'other_col'])
    .pipe(lambda x: x.set_axis(x.columns.str.split('_', expand=True), axis=1))
    .rename_axis(columns=['side', None])
    .stack('side')
    .reset_index()
)

print("\n方法一:MultiIndex重塑结果")
print(out_multiindex)

输出示例(顺序可能不同):

         date other_col   side  count  sum
0  2023-12-01         a   left      1    0
1  2023-12-01         a  right      4    2
2  2023-12-05         b   left      8    8
3  2023-12-05         b  right      7    3
4  2023-12-07         c   left      5    4
5  2023-12-07         c  right      9    5

方法二:结合melt和pivot函数

这种方法分两步进行:首先使用melt将宽格式数据“融化”为长格式,然后使用pivot将其重新组织为所需的结构。

ImgCreator AI
ImgCreator AI

一款AI图像生成工具,适合创建插图、动画和概念设计图像。

下载
  1. melt操作: df.melt(['date', 'other_col'], var_name='side')将除date和other_col之外的所有列转换为两列:side(包含原始列名)和value(包含对应的值)。
  2. 拆分列名: tmp['side'].str.split('_', n=1, expand=True)将side列中的原始列名(如right_count)拆分为side和col两部分。
  3. pivot操作: tmp.pivot(...)根据date, other_col, side作为新索引,col作为新列,value作为对应值进行透视。
  4. 清理: reset_index().rename_axis(columns=None)重置索引并清理透视产生的列名轴。
tmp = df.melt(['date', 'other_col'], var_name='temp_col_name')
tmp[['side', 'col']] = tmp['temp_col_name'].str.split('_', n=1, expand=True)

out_melt_pivot = (tmp.pivot(index=['date', 'other_col', 'side'],
                            columns='col', values='value')
                     .reset_index()
                     .rename_axis(columns=None)
)

print("\n方法二:melt + pivot重塑结果")
print(out_melt_pivot)

输出示例(顺序可能不同):

         date other_col   side  count  sum
0  2023-12-01         a   left      1    0
1  2023-12-01         a  right      4    2
2  2023-12-05         b   left      8    8
3  2023-12-05         b  right      7    3
4  2023-12-07         c   left      5    4
5  2023-12-07         c  right      9    5

方法三:使用janitor库的pivot_longer

janitor是一个强大的Python库,提供了许多便捷的数据清洗和处理功能,其中包括pivot_longer,它旨在简化类似R语言tidyr包中的pivot_longer操作。这种方法通常更简洁、易读。

首先,确保安装了pyjanitor库:

pip install pyjanitor

然后,导入并使用pivot_longer:

import janitor

out_janitor = df.pivot_longer(
    index=['date', 'other_col'],
    names_to=('side', '.value'),
    names_pattern=r'([^_]+)_([^_]+)'
)

print("\n方法三:janitor.pivot_longer重塑结果")
print(out_janitor)

关键参数解释:

  • index: 指定作为新DataFrame索引的列(不参与堆叠的列)。
  • names_to: 一个元组,用于指定如何将原始列名解析为新的列。
    • 'side':匹配正则表达式捕获组中的第一个部分,并将其命名为side列。
    • '.value':一个特殊关键字,表示匹配正则表达式捕获组中的剩余部分,并将其作为新的列名(如count和sum)。
  • names_pattern: 一个正则表达式,用于从原始列名中提取信息。r'([^_]+)_([^_]+)'表示匹配一个或多个非下划线字符(第一个捕获组),后跟一个下划线,再后跟一个或多个非下划线字符(第二个捕获组)。

输出示例:

         date other_col   side  count  sum
0  2023-12-01         a  right      4    2
1  2023-12-05         b  right      7    3
2  2023-12-07         c  right      9      5
3  2023-12-01         a   left      1    0
4  2023-12-05         b   left      8    8
5  2023-12-07         c   left      5    4

总结与注意事项

  • 选择方法:
    • MultiIndex方法:提供最大的灵活性,适用于列名模式复杂或需要精细控制中间步骤的场景。但代码可读性相对较低。
    • melt + pivot方法:是Pandas内置的经典重塑组合,逻辑清晰,适用于大多数通用场景。理解melt和pivot的工作原理是掌握Pandas数据重塑的关键。
    • janitor.pivot_longer方法:对于有规律的列名模式,此方法最为简洁和直观,大大提高了代码的可读性和编写效率。强烈推荐在日常数据处理中使用。
  • 性能考量: 对于非常大的DataFrame,不同的重塑方法可能在性能上有所差异。通常,Pandas的内置函数经过高度优化,而外部库如janitor也会利用这些优化。在极端性能敏感的场景下,可以进行基准测试。
  • 列名模式: 所有方法都依赖于对原始列名模式的理解和解析。确保正则表达式(在janitor方法中)或str.split(在Pandas内置方法中)能够准确地从列名中提取所需的部分。
  • 数据类型: 重塑操作可能会改变列的数据类型,特别是当melt操作将不同类型的列值合并到value列时。在后续分析前,可能需要进行数据类型转换。

掌握这些Pandas数据重塑技术,将使您能够更有效地组织和分析数据,为后续的数据探索、建模和可视化奠定坚实基础。

相关专题

更多
python开发工具
python开发工具

php中文网为大家提供各种python开发工具,好的开发工具,可帮助开发者攻克编程学习中的基础障碍,理解每一行源代码在程序执行时在计算机中的过程。php中文网还为大家带来python相关课程以及相关文章等内容,供大家免费下载使用。

746

2023.06.15

python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

634

2023.07.20

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

758

2023.07.25

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

617

2023.07.31

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

1260

2023.08.03

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

547

2023.08.04

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

577

2023.08.04

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

705

2023.08.11

Java 项目构建与依赖管理(Maven / Gradle)
Java 项目构建与依赖管理(Maven / Gradle)

本专题系统讲解 Java 项目构建与依赖管理的完整体系,重点覆盖 Maven 与 Gradle 的核心概念、项目生命周期、依赖冲突解决、多模块项目管理、构建加速与版本发布规范。通过真实项目结构示例,帮助学习者掌握 从零搭建、维护到发布 Java 工程的标准化流程,提升在实际团队开发中的工程能力与协作效率。

3

2026.01.12

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 0.6万人学习

Django 教程
Django 教程

共28课时 | 3万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.1万人学习

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

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