0

0

Pandas数据透视与向量化操作:高效聚合复杂数据集

DDD

DDD

发布时间:2025-09-10 14:07:00

|

791人浏览过

|

来源于php中文网

原创

Pandas数据透视与向量化操作:高效聚合复杂数据集

本教程旨在解决Pandas数据处理中常见的重复性select和merge操作问题。通过引入pivot函数和向量化计算,我们将展示如何将繁琐的多步骤数据筛选、合并和计算过程,简化为简洁、高效且易于维护的代码。文章将详细阐述如何利用这些强大的Pandas功能,实现复杂数据聚合与转换,显著提升代码的可读性和执行效率。

冗余数据处理的挑战

在处理大规模数据集时,我们经常需要根据多个条件对数据进行筛选、组合,并执行各种计算。传统的做法可能涉及多次使用dataframe.loc进行条件筛选,创建多个中间dataframe,然后通过pd.merge将它们合并,最后进行列之间的算术运算。这种方法虽然能够得到正确结果,但存在以下显著缺点:

  1. 代码冗余: 大量重复的筛选、合并和列操作使得代码量庞大,难以阅读和理解。
  2. 效率低下: 频繁创建中间DataFrame和执行merge操作会增加内存开销和计算时间,尤其对于百万级别甚至千万级别的数据集,性能瓶颈尤为突出。
  3. 维护困难: 随着业务逻辑的复杂化,修改或扩展现有代码变得更加困难,容易引入错误。

以下是一个典型场景的示例代码,展示了这种重复性操作:

import io
import pandas as pd

TESTDATA="""
enzyme  regions   N   length
AaaI    all       10  238045
AaaI    all       20  170393
AaaI    all       30  131782
AaaI    all       40  103790
AaaI    all       50  81241246
AaaI    all       60  62469
AaaI    all       70  46080
AaaI    all       80  31340
AaaI    all       90  17188
AaaI    captured  10  292735
AaaI    captured  20  229824
AaaI    captured  30  193605
AaaI    captured  40  163710
AaaI    captured  50  138271
AaaI    captured  60  116122
AaaI    captured  70  95615
AaaI    captured  80  73317
AaaI    captured  90  50316
AagI    all       10  88337
AagI    all       20  19144
AagI    all       30  11030
AagI    all       40  8093
AagI    all       50  6394
AagI    all       60  4991
AagI    all       70  3813
AagI    all       80  2759
AagI    all       90  1666
AagI    captured  10  34463
AagI    captured  20  19220
AagI    captured  30  15389
AagI    captured  40  12818
AagI    captured  50  10923
AagI    captured  60  9261
AagI    captured  70  7753
AagI    captured  80  6201
AagI    captured  90  4495
"""
df_stats = pd.read_csv(io.StringIO(TESTDATA), sep='\s+')

# 原始的重复性操作示例
df_cap_N90 = df_stats[(df_stats['N'] == 90) & (df_stats['regions'] == 'captured')].drop(columns=['regions', 'N'])
df_cap_N50 = df_stats[(df_stats['N'] == 50) & (df_stats['regions'] == 'captured')].drop(columns=['regions', 'N'])
df_all_N50 = df_stats[(df_stats['N'] == 50) & (df_stats['regions'] == 'all')].drop(columns=['regions', 'N'])

df_summ_cap_N50_all_N50 = pd.merge(df_cap_N50, df_all_N50, on='enzyme', how='inner', suffixes=('_cap_N50', '_all_N50'))
df_summ_cap_N50_all_N50['cap_N50_all_N50'] = (df_summ_cap_N50_all_N50['length_cap_N50'] -
                                              df_summ_cap_N50_all_N50['length_all_N50'])

df_summ_cap_N90_all_N50 = pd.merge(df_cap_N90, df_all_N50, on='enzyme', how='inner', suffixes=('_cap_N90', '_all_N50'))
df_summ_cap_N90_all_N50['cap_N90_all_N50'] = df_summ_cap_N90_all_N90['length_cap_N90'] - df_summ_cap_N90_all_N90['length_all_N50']

df_summ = pd.merge(df_summ_cap_N50_all_N50.drop(columns=['length_cap_N50', 'length_all_N50']),
                   df_summ_cap_N90_all_N50.drop(columns=['length_cap_N90', 'length_all_N50']),
                   on='enzyme', how='inner')
print("原始方法计算结果:")
print(df_summ)

Pandas高效聚合与转换策略:pivot与向量化操作

为了克服上述问题,我们可以利用Pandas的pivot函数和其强大的向量化操作能力。pivot函数能够将DataFrame从“长格式”转换为“宽格式”,将指定列的唯一值转换为新的列,从而大大简化后续的计算。结合向量化操作,我们可以避免显式的循环和多次合并,直接对整个列或DataFrame进行高效运算。

核心思想是:

  1. 预筛选: 仅保留需要参与计算的行,减少数据量。
  2. 数据透视: 使用pivot将关键的分类变量(如regions和N)转化为新的列,使得需要比较的数据点在同一行上。
  3. 向量化计算: 直接对透视后的DataFrame进行列与列之间的数学运算。

示例代码与详细解析

我们将使用df_stats数据集,目标是计算cap_N50_all_N50 (captured N50 - all N50) 和 cap_N90_all_N50 (captured N90 - all N50)。

Speech Studio
Speech Studio

微软语音服务,提供语音到文本、文本到语音和语音翻译功能。

下载
# 1. 筛选相关数据
# 仅保留N为50或90的行,因为只有这些N值参与最终计算
filtered_df = df_stats.loc[df_stats["N"].isin([50, 90])]

# 2. 使用pivot进行数据透视
# index='enzyme':以enzyme作为新的行索引
# columns=['regions', 'N']:将regions和N的组合作为新的列索引(多级列索引)
# values='length':透视后单元格的值取自length列
pivoted_df = filtered_df.pivot(index="enzyme", columns=["regions", "N"], values="length")
print("\n透视后的DataFrame (pivoted_df):")
print(pivoted_df)

# 3. 执行向量化计算
# 提取'captured'区域的N50和N90长度
captured_lengths = pivoted_df["captured"]
# 提取'all'区域的N50长度
all_N50_length = pivoted_df[("all", 50)]

# 计算 (captured N50 - all N50) 和 (captured N90 - all N50)
# captured_lengths.sub(all_N50_length, axis=0)
# axis=0 表示按行进行广播,即captured_lengths的每一行都减去all_N50_length的对应行值
result_df = captured_lengths.sub(all_N50_length, axis=0)

# 4. 调整列名并重置索引
# 为结果列添加前缀和后缀,使其符合目标输出格式
# add_prefix("cap_N"):为'captured'下的N值(50, 90)添加前缀'cap_N'
# add_suffix("_all_N50"):为所有结果列添加后缀'_all_N50'
final_output = result_df.add_prefix("cap_N").add_suffix("_all_N50").reset_index()

print("\n最终优化后的计算结果 (final_output):")
print(final_output)

代码解析:

  1. df_stats.loc[df_stats["N"].isin([50, 90])]: 首先,我们筛选出N列值为50或90的行。这是一个重要的优化步骤,因为它减少了后续pivot操作的数据量,提高了效率。
  2. .pivot(index="enzyme", columns=["regions", "N"], values="length"): 这是核心步骤。
    • index="enzyme":enzyme列的值将成为新DataFrame的行索引。
    • columns=["regions", "N"]:regions和N列的组合将构成新的多级列索引。例如,('captured', 50)和('all', 50)将成为独立的列。
    • values="length":透视后新列中的值将从原始DataFrame的length列获取。 经过这一步,我们得到了一个宽格式的DataFrame pivoted_df,其中所有需要比较的length值都已排列在同一行上,方便后续计算。
  3. pivoted_df["captured"].sub(pivoted_df[("all", 50)], axis=0):
    • pivoted_df["captured"]:这会选择多级列索引中第一级为'captured'的所有列,即('captured', 50)和('captured', 90)。
    • pivoted_df[("all", 50)]:这会选择多级列索引中精确匹配('all', 50)的列。
    • .sub(..., axis=0):这是Pandas的向量化减法操作。它将captured_lengths中的每一列(('captured', 50)和('captured', 90))分别减去all_N50_length列。axis=0确保操作是按行进行的,即每个enzyme的对应值相减。
  4. .add_prefix("cap_N").add_suffix("_all_N50").reset_index():
    • .add_prefix("cap_N"):为当前列名(例如50, 90)添加前缀"cap_N",变为"cap_N50","cap_N90"。
    • .add_suffix("_all_N50"):为所有列名添加后缀"_all_N50",最终形成"cap_N50_all_N50"和"cap_N90_all_N50"。
    • .reset_index():将enzyme索引转换回常规列,完成最终输出格式。

优势与注意事项

优势

  • 代码简洁性: 显著减少了代码行数,从数十行缩减到几行,极大地提高了代码的可读性和可维护性。
  • 执行效率: pivot和向量化操作在底层通常由C语言实现,相比于Python层的循环和多次merge,具有更高的执行效率,尤其适用于大数据集。
  • 可扩展性: 当需要添加更多N值或regions组合的计算时,只需修改isin()筛选条件和后续的列选择逻辑,而无需复制粘贴大量代码。
  • 减少中间DataFrame: 避免了创建大量的临时DataFrame,降低了内存消耗。

注意事项

  • 数据透视的适用性: pivot函数要求index、columns和values的组合在原始数据中必须是唯一的。如果存在重复组合,Pandas会报错。在这种情况下,应考虑使用pivot_table,它允许指定聚合函数来处理重复值。
  • 多级列索引: pivot操作常常会生成多级列索引。理解和正确使用多级索引是高效操作的关键。例如,通过元组('all', 50)来选择特定列。
  • 列名管理: pivot后的列名可能不是最终需要的格式。需要灵活运用add_prefix、add_suffix、rename等方法来调整列名,使其符合业务需求。
  • 内存消耗: 尽管比多次merge更优,但如果columns参数包含大量唯一值,生成的宽格式DataFrame可能会非常宽,占用大量内存。在极端情况下,可能需要考虑其他聚合策略,如groupby().apply()结合自定义函数。
  • 缺失值处理: 如果原始数据中某些index、columns组合不存在,pivot操作会引入NaN(Not a Number)值。在进行后续计算前,可能需要根据业务逻辑对这些NaN值进行填充或删除。

总结

通过本教程,我们深入探讨了如何利用Pandas的pivot函数和向量化操作来优化数据聚合与转换过程。这种方法不仅显著提升了代码的简洁性、可读性和可维护性,还在处理大规模数据集时展现出卓越的性能优势。掌握pivot和向量化计算是成为高效Pandas用户的关键一步,能够帮助开发者摆脱冗余的select和merge操作,编写出更加优雅和高效的数据处理代码。在面对复杂的数据转换需求时,始终优先考虑Pandas提供的内置高效函数,以充分发挥其强大功能。

相关专题

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

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

741

2023.06.15

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

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

634

2023.07.20

python能做什么
python能做什么

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

756

2023.07.25

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

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

617

2023.07.31

python教程
python教程

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

1259

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

c++主流开发框架汇总
c++主流开发框架汇总

本专题整合了c++开发框架推荐,阅读专题下面的文章了解更多详细内容。

3

2026.01.09

热门下载

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

精品课程

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

共4课时 | 0.6万人学习

Django 教程
Django 教程

共28课时 | 2.9万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.1万人学习

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

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