跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

Pandas高效数据聚合:利用Pivot与向量化操作简化复杂统计计算

本文旨在解决Pandas数据聚合中常见的冗余操作问题,特别是当需要从原始数据框中提取多个子集并进行合并计算时。通过引入pivot函数重塑数据结构,并结合Pandas的向量化操作(如sub),我们将展示如何以更简洁、高效且易于维护的方式实现复杂的统计计算,从而避免大量中间DataFrame和merge操作,显著提升代码质量和执行效率。 挑战:冗余的Pandas数据聚合 在处理大规模数据集时,我们经常需要根据不同的条件筛选数据,然后对这些子集进行聚合或计算,并将结果合并。传统的做法可能涉及多次筛选(df[condition])、创建临时dataframe,然后通过merge操作将这些结果拼接起来。这种方法在逻辑上虽然可行,但在面对复杂或多样的聚合需求时,会导致代码变得冗长、重复且难以维护。 考虑以下场景:我们需要从一个包含生物酶统计数据的数据框df_stats中,提取特定N值(如N=50, N=90)和区域类型('all', 'captured')的数据,并计算不同组合之间的长度差异。例如,计算captured N50与all N50之间的长度差异,以及captured N90与all N50之间的长度差异。如果采用逐个筛选和合并的方式,代码会如下所示:
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_N50['length_cap_N90'] - df_summ_cap_N90_all_N50['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)
上述代码虽然实现了预期功能,但创建了多个中间DataFrame并进行了多次merge操作,这不仅降低了代码的可读性和维护性,也可能在处理 大数据 集时影响性能。 解决方案:利用Pandas Pivot与向量化操作 Pandas的pivot函数能够将DataFrame从“长格式”重塑为“宽格式”,这在需要基于多个分类变量进行聚合和比较时非常有用。结合向量化操作,我们可以极大地简化上述过程。 用Apache Spark进行大数据处理 本文档主要讲述的是用Apache Spark进行大数据处理——第一部分:入门介绍;Apache Spark是一个围绕速度、易用性和复杂分析构建的大数据处理框架。最初在2009年由加州大学伯克利分校的AMPLab开发,并于2010年成为Apache的开源项目之一。 在这个Apache Spark文章系列的第一部分中,我们将了解到什么是Spark,它与典型的MapReduce解决方案的比较以及它如何为大数据处理提供了一套完整的工具。希望本文档会给有需要的朋友带来帮助;感 下载 核心思路是: **

相关文章