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

聖光之護
发布: 2025-07-23 14:32:01
原创
848人浏览过

如何在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
登录后复制

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

序列猴子开放平台
序列猴子开放平台

具有长序列、多模态、单模型、大数据等特点的超大规模语言模型

序列猴子开放平台 0
查看详情 序列猴子开放平台

在管道操作中的应用: 如果需要将此操作集成到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中复杂的排序需求,从而更高效地处理和分析数据。

以上就是如何在Pandas中按组聚合值排序并保留原始行顺序的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
热门推荐
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

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