Pandas DataFrame多列重塑:将宽格式数据转换为长格式的实用技巧

Pandas DataFrame多列重塑:将宽格式数据转换为长格式的实用技巧

本文探讨了在pandas dataframe中将多列宽格式数据重塑为长格式的多种方法。通过示例,详细介绍了使用pandas原生函数如`melt`与`pivot`、基于multiindex的高级重塑技巧,以及利用`pyjanitor`库中`pivot_longer`函数的便捷操作。旨在帮助用户高效地规整数据,使其更适合分析和可视化。

在数据分析和处理中,我们经常会遇到需要将DataFrame中的“宽格式”数据转换为“长格式”数据的情况。宽格式数据通常表现为,多个相关联的指标被分散在不同的列中,且列名中包含了这些指标的分类信息。例如,原始数据中可能包含 right_count, right_sum, left_count, left_sum 等列,我们希望将其重塑为 side, count, sum 三列,其中 side 列表示“right”或“left”,count 和 sum 列分别包含对应的值。这种转换对于后续的数据聚合、可视化和建模至关重要。

以下是一个典型的宽格式DataFrame示例:

import pandas as pddf = 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)

期望的输出格式如下:

         date other_col   side  count  sum0  2023-12-01         a  right      4    21  2023-12-05         b  right      7    32  2023-12-07         c  right      9    53  2023-12-01         a   left      1    04  2023-12-05         b   left      8    85  2023-12-07         c   left      5    4

接下来,我们将介绍几种实现这种数据重塑的有效方法。

方法一:使用 melt 和 pivot 进行数据重塑

pandas.melt 函数用于将DataFrame从宽格式转换为长格式,它会将指定的列“融化”成两列:一列包含原列名(通常命名为variable),另一列包含对应的值(通常命名为value)。之后,我们可以利用 str.split 分割 variable 列,并结合 pivot 函数将数据重新排列成我们需要的长格式。

# 步骤1: 使用 melt 函数将 'right_count', 'right_sum', 'left_count', 'left_sum' 列融化# id_vars 指定不变的标识列tmp = df.melt(id_vars=['date', 'other_col'], var_name='original_col_name')# 步骤2: 从新的 'original_col_name' 列中分割出 'side' 和 'metric_type'# n=1 表示只分割一次,expand=True 将结果扩展为新的DataFrame列tmp[['side', 'metric_type']] = tmp['original_col_name'].str.split('_', n=1, expand=True)# 步骤3: 使用 pivot 函数将 'metric_type' 重新作为列,'value' 作为值# index 指定新的行索引,columns 指定新的列名,values 指定新的值out_melt_pivot = (tmp.pivot(index=['date', 'other_col', 'side'],                            columns='metric_type',                            values='value')                     .reset_index() # 将索引重置为列                     .rename_axis(columns=None) # 移除列索引的名称                 )print("n方法一 (melt + pivot) 结果:")print(out_melt_pivot)

优点:

这是Pandas中处理宽到长格式转换的常用且直观的方法。分步操作清晰,易于理解每一步的作用。

缺点:

需要多个步骤,代码可能稍显冗长。

方法二:基于 MultiIndex 的高级重塑

这种方法利用Pandas的MultiIndex功能在列级别创建分层索引,然后通过 stack 操作将部分索引级别转换为行数据。这是一种更为紧凑和强大的Pandas原生解决方案。

# 步骤1: 设置 'date' 和 'other_col' 为行索引# 步骤2: 使用 pipe 函数链式操作,通过 str.split 创建列的MultiIndex#         x.columns.str.split('_', expand=True) 会将 'right_count' 分割为 ('right', 'count')# 步骤3: 重命名列索引的级别,使其更具可读性# 步骤4: 对 'side' 级别进行 stack 操作,将其从列转换为行# 步骤5: 重置索引,将所有索引级别转换为常规列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]) # 'None' 表示第二个级别没有名称   .stack('side') # 对 'side' 级别进行堆叠   .reset_index())print("n方法二 (MultiIndex) 结果:")print(out_multiindex)

优点:

纯Pandas操作,无需引入外部库。对于复杂的重塑任务,MultiIndex提供了强大的灵活性。

缺点:

概念相对复杂,对于初学者可能不易理解。代码的可读性不如 melt + pivot 或 pyjanitor 直观。

方法三:借助 pyjanitor 库简化操作

pyjanitor 是一个为Pandas提供额外数据清理和转换功能的库,其中的 pivot_longer 函数专门用于简化从宽格式到长格式的转换,其灵感来源于R语言的 tidyr::pivot_longer。

首先,如果尚未安装 pyjanitor,请通过pip安装

pip install pyjanitor

然后,可以使用以下代码进行重塑:

import janitor # 导入 janitor 库# 使用 pivot_longer 函数# index: 指定不变的标识列# names_to: 指定新的列名元组,其中 '.value' 是一个特殊占位符,表示将原始列名的剩余部分作为新列名# names_pattern: 使用正则表达式来匹配原始列名并捕获要提取的部分out_janitor = df.pivot_longer(    index=['date', 'other_col'],    names_to=('side', '.value'), # 'side' 是第一个捕获组,'.value' 是第二个捕获组    names_pattern=r'([^_]+)_([^_]+)' # 匹配 'xxx_yyy' 模式,捕获 'xxx' 和 'yyy')print("n方法三 (pyjanitor.pivot_longer) 结果:")print(out_janitor)

优点:

代码极其简洁和直观,尤其是在列名有规律时。names_to 和 names_pattern 参数提供了强大的模式匹配能力。易于理解和维护。

缺点:

需要安装额外的第三方库 pyjanitor。

注意事项与总结

选择方法:对于简单的宽到长格式转换,melt 和 pivot 组合是一个稳健的选择,因为它纯粹基于Pandas且易于理解。如果数据重塑逻辑复杂,或者希望追求更紧凑的Pandas原生代码,可以尝试MultiIndex方法,但需要对Pandas的索引操作有较深入的理解。对于追求代码简洁性和高可读性,并且不介意引入第三方库的用户,pyjanitor.pivot_longer 是一个极佳的选择,尤其适用于列名具有明确模式的情况。正则表达式 在使用 str.split 或 names_pattern 时,理解和正确使用正则表达式至关重要,它决定了如何从原始列名中提取新的分类信息。数据类型: 重塑操作后,新生成的列(如 count 和 sum)的数据类型可能会变为 object。在进行数值计算前,请确保将其转换为适当的数值类型(例如 int 或 float)。长格式数据的好处: 将数据转换为长格式通常更适合数据分析、统计建模和使用seaborn、matplotlib等库进行可视化,因为它遵循“整洁数据”(Tidy Data)原则,即每列是一个变量,每行是一个观察值。

掌握这些数据重塑技巧,将使您在处理Pandas DataFrame时更加高效和灵活,从而更好地准备数据以进行深入分析。

以上就是Pandas DataFrame多列重塑:将宽格式数据转换为长格式的实用技巧的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1381174.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月14日 22:43:56
下一篇 2025年12月14日 22:44:11

相关推荐

  • Pandas数据重塑教程:高效堆叠多列的多种方法

    本文详细介绍了在pandas dataframe中将多列堆叠并重塑为更简洁结构的三种高效方法。通过实例代码,分别演示了如何利用multiindex、`melt`与`pivot`组合以及`janitor`库的`pivot_longer`函数来实现数据从宽格式到长格式的转换,旨在帮助用户根据具体场景选择…

    2025年12月14日
    000
  • 深入理解PLY词法分析中的常见陷阱与解决方案

    本文旨在解决使用ply (python lex-yacc) 进行词法分析时常见的正则表达错误,特别是关于令牌规则函数未返回令牌以及规则优先级冲突的问题。通过详细解析`pass`语句的误用和通用规则对特定规则的“遮蔽”效应,文章提供了两种有效的解决方案:调整规则定义顺序以确保特定规则优先匹配,或将相关…

    2025年12月14日
    000
  • Python字符串处理:从指定关键词处截取右侧内容

    本文详细介绍了在Python中如何高效地从字符串中提取指定关键词右侧的内容。针对语音转文本等场景中常见的需求,文章通过对比传统方法与正则表达式,重点讲解了如何使用`re`模块的`sub()`和`search()`函数,以简洁、健壮的方式实现字符串的精确截取,并涵盖了关键词存在性检查等实用技巧,确保处…

    2025年12月14日
    000
  • Python入门如何操作正则表达式_Python入门文本匹配的强大工具

    正则表达式是Python中处理文本模式匹配的强大工具。1、通过import re导入模块,使用re.match()从字符串开头匹配,如re.match(r’abc’, ‘abcdef’)成功匹配。2、re.search()在全文查找首个匹配项,如re.…

    2025年12月14日
    000
  • Python CSV 文件的读取方法

    读取CSV文件常用方法包括:1. 使用csv模块的reader读取为列表;2. 用DictReader按表头读取为字典;3. 用pandas.read_csv处理数据分析任务,支持分隔符、编码设置及分块读取,推荐根据需求选择。 读取 CSV 文件在 Python 中非常常见,主要使用内置的 csv …

    2025年12月14日
    000
  • Python实现文本文件行号自动递增追加写入

    本文详细介绍了如何使用python向文本文件追加新数据,并为每行数据自动生成一个带零填充的递增序号。通过结合文件`a+`模式、文件指针重置、读取现有行数以及f-string格式化,本教程提供了一种高效且健壮的方法来管理带有序列号的日志或数据文件,确保数据的一致性和可追溯性。 在日常的数据处理和日志记…

    2025年12月14日
    000
  • Python矩阵嵌套循环性能优化:Numba与条件重排实战

    本文旨在解决python中处理矩阵的深度嵌套循环效率低下问题。通过引入numba进行即时编译(jit)和策略性地重新排序循环及条件判断,实现“提前退出”,显著提升数值计算性能。该方法将详细展示如何结合这两种技术,将原本耗时数秒甚至更长的计算过程优化至毫秒级别,同时提供完整的代码示例和最佳实践建议。 …

    2025年12月14日
    000
  • Python 文件索引与搜索的实现方法

    答案:使用pathlib和os模块遍历目录,构建包含文件元数据的索引列表,通过关键字匹配实现文件名与内容搜索,并可用defaultdict优化查询效率。 在Python中实现文件索引与搜索,核心是遍历目录结构、提取文件信息并建立可快速查询的数据结构。常见场景包括本地文件检索、日志分析、代码库搜索等。…

    2025年12月14日
    000
  • Pandas DataFrame多列堆叠与重塑技巧

    本文将深入探讨在pandas dataframe中将多对相关列(如`right_count`, `right_sum`, `left_count`, `left_sum`)高效重塑为更紧凑长格式(如`side`, `count`, `sum`)的多种方法。我们将介绍基于multiindex和`sta…

    2025年12月14日
    000
  • Docker 容器中的 Python 环境优化

    选择轻量基础镜像如python:3.x-slim或alpine,合理分层Dockerfile以利用缓存,先装依赖再复制代码,使用多阶段构建,优化pip安装参数如–no-cache-dir,创建非root用户运行容器,排除无关文件,控制资源占用,提升安全性与性能。 在 Docker 容器中…

    2025年12月14日
    000
  • 精准控制 Pylint 检查:针对特定模块或文件模式禁用规则

    Pylint 默认不支持在配置文件中基于文件路径或正则表达式禁用特定检查。本文将探讨通过 Pylint 的内置控制消息、结合外部脚本的“两阶段”检查方案,以及 `ignore-patterns` 选项的适用场景与局限性,帮助开发者更灵活地管理代码质量检查,避免不必要的警告,提升开发效率。 引言:Py…

    2025年12月14日
    000
  • 在DynamoDB中实现高效自增ID的两种策略

    本文深入探讨了在Amazon DynamoDB中实现类似关系型数据库自增ID的两种高效策略。首先,我们将介绍如何利用原子计数器来生成全局唯一的序列号,并通过两步操作确保数据一致性与无竞争条件。其次,文章将详细阐述如何通过巧妙设计排序键(Sort Key)在项目集合内实现局部序列自增,并结合条件写入机…

    2025年12月14日
    000
  • Pandas MultiIndex DataFrame 多级自定义分组聚合教程

    本教程旨在解决pandas multiindex dataframe在不同索引级别上应用不同分组聚合规则的挑战。我们将演示如何通过重置索引、对特定级别进行字符串转换,然后执行多列分组聚合来达到自定义的数据汇总效果,从而实现对复杂数据结构的灵活处理。 1. 引言与问题背景 在数据分析中,Pandas …

    2025年12月14日
    000
  • 使用 Pylint 配置忽略特定未使用的参数

    本文旨在介绍如何通过配置 Pylint 的 `.pylintrc` 文件,来忽略特定未使用的参数,从而避免不必要的 `unused-argument` 警告,提高代码检查的效率和准确性。 Pylint 是一个强大的 Python 代码静态分析工具,它可以帮助开发者发现代码中的潜在问题,并提高代码质量…

    2025年12月14日
    000
  • 使用Python和正则表达式从字符串中提取关键词右侧文本

    本文将详细介绍如何使用python,特别是正则表达式,从字符串中截取并保留指定关键词右侧的内容。通过高效的正则表达式模式,我们可以精确地移除关键词及其左侧的所有文本,从而获得所需的目标子串。这对于处理音频转录等需要基于特定标记进行内容筛选的场景尤为实用。 Python字符串:从指定关键词开始截取右侧…

    2025年12月14日
    000
  • 深入理解直接访问数组排序:键值分离与整体排序机制

    直接访问数组排序是一种利用键值作为数组索引的线性时间排序算法。它通过创建一个足够大的辅助数组,将待排序对象的键值映射为该数组的索引,从而实现对象的直接存储。在遍历辅助数组时,按索引顺序提取对象,即可得到排序后的结果。本文将详细解析其工作原理,包括键与值的存储方式、算法步骤、时间空间复杂度及适用场景,…

    2025年12月14日
    000
  • 使用 Pylint 配置文件忽略特定未使用参数

    本文介绍如何使用 Pylint 配置文件(`.pylintrc`)中的 `–ignored-argument-names` 选项,来忽略特定函数或方法中未使用的参数,从而避免产生 `W0613: Unused argument` 警告,而无需完全禁用 `unused-argument` …

    2025年12月14日
    000
  • Pandas str.fullmatch 处理 NaN 值的行为解析与解决方案

    本文深入探讨了pandas `str.fullmatch` 方法在处理包含 `nan` 值的series时,与布尔值 `false` 进行比较所产生的非预期行为。我们将解析 `nan == false` 表达式的求值逻辑,并通过详细示例展示其如何影响条件判断。最后,提供多种实用的解决方案,包括使用 …

    2025年12月14日
    000
  • Python中批量处理NC文件并动态生成图表标题的教程

    本教程旨在解决使用Python和Matplotlib批量绘制NC(NetCDF)文件数据时,如何为每个生成的图表动态设置标题的问题。通过分析原始代码中标题设置失败的原因,我们将提供一个结构化的解决方案,包括正确的数据加载、时间信息提取与格式化,以及在绘图循环中动态关联并应用标题的方法,确保每个图表都…

    2025年12月14日
    000
  • Python教程:按月份和年份批量分割数据并进行时间关联

    本教程详细介绍了如何使用python将一个大型数据列表(如客户邮件列表)按固定大小分块,并为每个分块数据关联特定的月份和年份。通过结合列表切片、循环生成时间序列和字典映射,我们能够高效地将数据组织成按时间周期划分的结构,适用于预订系统或数据管理等场景。 在许多数据处理场景中,我们可能需要将一个包含大…

    2025年12月14日
    000

发表回复

登录后才能评论
关注微信