0

0

如何在Pandas中按组聚合值排序并保留原始行顺序

聖光之護

聖光之護

发布时间:2025-07-23 14:32:01

|

854人浏览过

|

来源于php中文网

原创

如何在Pandas中按组聚合值排序并保留原始行顺序

本教程详细介绍了如何在Pandas DataFrame中实现一种特殊的排序需求:根据某一列(如col1)进行分组,然后根据另一列(如col2)在各组内的聚合统计值(如最小值)来确定组的整体顺序,同时保留各组内部行的原始相对顺序。文章提供了使用numpy.argsort结合groupby().transform()的“规范”方法,并讨论了sort_values结合key参数的替代方案及其适用场景。

在数据分析和处理中,我们经常需要对dataframe进行排序。pandas提供了强大的sort_values()方法,可以根据一个或多个列的值进行排序。然而,当需求变得更复杂时,例如需要根据某个分组的聚合值来排序整个组的顺序,同时又希望保留组内行的原始相对顺序时,常规的sort_values()方法就显得力不从心了。

考虑以下示例DataFrame:

import pandas as pd
import numpy as np

df = pd.DataFrame({'col1': ['A', 'B', 'A', 'B', 'C'],
                   'col2': [3, 1, 2, 4, 3],
                   'col3': [10, 20, 30, 40, 50]})
print("原始 DataFrame:")
print(df)

输出:

原始 DataFrame:
  col1  col2  col3
0    A     3    10
1    B     1    20
2    A     2    30
3    B     4    40
4    C     3    50

我们的目标是:

  1. 根据col1进行分组。
  2. 计算每个组的col2最小值。
  3. 根据这些最小值对组的整体顺序进行排序(例如,B组的col2最小值为1,A组为2,C组为3,所以最终顺序应为B组在前,A组次之,C组最后)。
  4. 在每个组内部,保持行的原始相对顺序。

期望的输出如下:

  col1  col2  col3
1    B     1    20
3    B     4    40
0    A     3    10
2    A     2    30
4    C     3    50

请注意,对于A组,原始顺序是索引0(col2=3)在前,索引2(col2=2)在后,最终输出保持了这个顺序。

方法一:使用 numpy.argsort 和 groupby().transform() (推荐)

这是实现上述特定需求的“规范”方法,它能够精确地按照组的聚合值排序组,同时完美保留组内行的原始相对顺序。

核心原理:

  1. df.groupby('col1')['col2'].transform('min'): 这一步是关键。groupby('col1')将DataFrame按col1分组,然后选择col2列。transform('min')的作用是将每个组的col2最小值计算出来,并将这个最小值“广播”回原始DataFrame的形状,即,同一组内的所有行都会被赋予该组的最小值。 例如,对于df,transform('min')会生成一个Series:
    0    2  (A组的min(col2)是2)
    1    1  (B组的min(col2)是1)
    2    2  (A组的min(col2)是2)
    3    1  (B组的min(col2)是1)
    4    3  (C组的min(col2)是3)
    dtype: int64
  2. np.argsort(...): numpy.argsort()函数返回将数组(或Series)排序所需的索引数组。当应用于上述transform结果时,它会返回一个索引序列,这些索引是根据每个原始行对应的组最小值进行排序的。由于np.argsort在遇到相同值时会保留原始相对顺序,这正是我们需要的特性。 对于 [2, 1, 2, 1, 3],np.argsort会返回 [1, 3, 0, 2, 4]。
  3. df.iloc[...]: iloc是Pandas中基于整数位置的索引器。我们将np.argsort返回的索引数组传递给iloc,DataFrame就会按照这些新的索引顺序进行重排。

代码示例:

# 方法一:使用 numpy.argsort 和 groupby().transform()
out_method1 = df.iloc[np.argsort(df.groupby('col1')['col2'].transform('min'))]
print("\n方法一输出 (组间按min(col2)排序,组内保留原始顺序):")
print(out_method1)

输出:

方法一输出 (组间按min(col2)排序,组内保留原始顺序):
  col1  col2  col3
1    B     1    20
3    B     4    40
0    A     3    10
2    A     2    30
4    C     3    50

这与我们期望的输出完全一致。

燕雀Logo
燕雀Logo

为用户提供LOGO免费设计在线生成服务

下载

在管道操作中的应用: 如果需要将此操作集成到Pandas的链式方法调用中(即管道操作),可以使用lambda函数:

out_pipeline = df.iloc[lambda d: np.argsort(d.groupby('col1')['col2'].transform('min'))]
print("\n管道操作中的方法一输出:")
print(out_pipeline)

方法二:使用 sort_values 的 key 参数 (Pandas 1.1+)

Pandas 1.1版本引入了sort_values()方法的key参数,它允许在排序之前对by参数指定的列应用一个函数。这个方法在某些场景下也非常有用,但需要注意的是,它与方法一在处理组内顺序上有所不同。

核心原理:

  1. by='col2': 指定主要的排序依据是col2列。
  2. key=lambda s: s.groupby(df['col1']).transform('min'): key参数接收一个函数,这个函数会应用于by参数指定的列(在这里是df['col2'],函数中的s代表df['col2'])。 因此,s.groupby(df['col1']).transform('min')会为df['col2']的每个值生成一个对应的排序键(即其所在组的col2最小值)。 sort_values会根据这些“键”进行排序。
  3. 组内排序差异: 当多个行的key值相等时(即它们属于同一个组),sort_values会退回到使用by参数指定的列(col2)进行二次排序。这意味着,如果同一组内有多个行,它们将根据其自身的col2值进行排序。

代码示例:

# 方法二:使用 sort_values 的 key 参数
# 注意:此方法会在组内根据 by 参数(col2)进行二次排序
out_method2 = df.sort_values(by='col2',
                             key=lambda s: s.groupby(df['col1']).transform('min'))
print("\n方法二输出 (组间按min(col2)排序,组内按col2排序):")
print(out_method2)

输出:

方法二输出 (组间按min(col2)排序,组内按col2排序):
  col1  col2  col3
1    B     1    20
3    B     4    40
2    A     2    30  # 注意:A组内部顺序与方法一不同
0    A     3    10  # 注意:A组内部顺序与方法一不同
4    C     3    50

与方法一的输出对比,A组内部的行顺序发生了变化。在方法一中,A组的原始顺序(索引0在前,索引2在后)得以保留。而在方法二中,由于key值相同(都是2),sort_values会根据by='col2'进行二次排序,导致col2值为2的行(索引2)排在了col2值为3的行(索引0)前面。

注意事项与总结

  • 选择依据

    • 如果你需要根据组的聚合值排序整个组,并且严格保留组内行的原始相对顺序,那么方法一(np.argsort与transform结合)是最佳选择。它精确地匹配了示例中的需求。
    • 如果你需要根据组的聚合值排序整个组,并且希望在组内部也根据某个列(例如col2)进行二次排序,那么方法二(sort_values的key参数)更为简洁和适用。
  • 性能考量:对于大型数据集,这两种方法通常都具有良好的性能,因为它们利用了Pandas和NumPy底层的优化C实现。在绝大多数实际应用中,性能差异不会成为主要瓶颈。

掌握这两种方法,可以灵活应对Pandas中复杂的排序需求,从而更高效地处理和分析数据。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
Python 时间序列分析与预测
Python 时间序列分析与预测

本专题专注讲解 Python 在时间序列数据处理与预测建模中的实战技巧,涵盖时间索引处理、周期性与趋势分解、平稳性检测、ARIMA/SARIMA 模型构建、预测误差评估,以及基于实际业务场景的时间序列项目实操,帮助学习者掌握从数据预处理到模型预测的完整时序分析能力。

53

2025.12.04

lambda表达式
lambda表达式

Lambda表达式是一种匿名函数的简洁表示方式,它可以在需要函数作为参数的地方使用,并提供了一种更简洁、更灵活的编码方式,其语法为“lambda 参数列表: 表达式”,参数列表是函数的参数,可以包含一个或多个参数,用逗号分隔,表达式是函数的执行体,用于定义函数的具体操作。本专题为大家提供lambda表达式相关的文章、下载、课程内容,供大家免费下载体验。

205

2023.09.15

python lambda函数
python lambda函数

本专题整合了python lambda函数用法详解,阅读专题下面的文章了解更多详细内容。

190

2025.11.08

Python lambda详解
Python lambda详解

本专题整合了Python lambda函数相关教程,阅读下面的文章了解更多详细内容。

49

2026.01.05

数据分析的方法
数据分析的方法

数据分析的方法有:对比分析法,分组分析法,预测分析法,漏斗分析法,AB测试分析法,象限分析法,公式拆解法,可行域分析法,二八分析法,假设性分析法。php中文网为大家带来了数据分析的相关知识、以及相关文章等内容。

467

2023.07.04

数据分析方法有哪几种
数据分析方法有哪几种

数据分析方法有:1、描述性统计分析;2、探索性数据分析;3、假设检验;4、回归分析;5、聚类分析。本专题为大家提供数据分析方法的相关的文章、下载、课程内容,供大家免费下载体验。

279

2023.08.07

网站建设功能有哪些
网站建设功能有哪些

网站建设功能包括信息发布、内容管理、用户管理、搜索引擎优化、网站安全、数据分析、网站推广、响应式设计、社交媒体整合和电子商务等功能。这些功能可以帮助网站管理员创建一个具有吸引力、可用性和商业价值的网站,实现网站的目标。

731

2023.10.16

数据分析网站推荐
数据分析网站推荐

数据分析网站推荐:1、商业数据分析论坛;2、人大经济论坛-计量经济学与统计区;3、中国统计论坛;4、数据挖掘学习交流论坛;5、数据分析论坛;6、网站数据分析;7、数据分析;8、数据挖掘研究院;9、S-PLUS、R统计论坛。想了解更多数据分析的相关内容,可以阅读本专题下面的文章。

508

2024.03.13

Java编译相关教程合集
Java编译相关教程合集

本专题整合了Java编译相关教程,阅读专题下面的文章了解更多详细内容。

5

2026.01.21

热门下载

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

精品课程

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

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