Pandas中基于多列条件进行排名及处理并列情况的教程

霞舞
发布: 2025-12-02 14:10:19
原创
710人浏览过

Pandas中基于多列条件进行排名及处理并列情况的教程

本教程详细介绍了如何在pandas dataframe中实现多级条件排名,特别是当主排名列存在并列情况时,如何利用次要列和第三列作为破平器。通过构建一个加权复合分数,并结合`rank`函数的`method='dense'`参数,我们能够精确地为数据行分配排名,有效解决复杂的排名逻辑需求,确保排名结果的准确性和一致性。

Pandas DataFrame多级条件排名与并列处理

在数据分析中,我们经常需要对数据进行排名。然而,简单的单列排名往往无法满足复杂的需求,特别是在存在并列值时,我们可能需要依据其他列作为“破平器”来进一步区分排名。本教程将深入探讨如何在Pandas DataFrame中实现这种多级条件排名逻辑。

问题场景描述

假设我们有一个包含多个分数(例如DScore, EScore, Total Score)的DataFrame,我们希望根据'Total Score'列对数据进行排名。但如果'Total Score'值相同,则需要参考'EScore'进行排名;如果'EScore'也相同,则进一步参考'DScore'。只有当所有指定列的值都相同时,这些行才会被赋予相同的排名。

以下是我们的原始DataFrame示例:

import pandas as pd

df = pd.DataFrame({
    "DScore": [2, 2, 3, 4, 5],
    "EScore": [6, 7, 9, 9, 10],
    "Total Score": [17, 15, 15, 23, 25]
})

print("原始DataFrame:")
print(df)
登录后复制

期望的排名结果如下(注意索引1和2的Total Score均为15,但EScore不同,因此排名不同;索引2和3的Total Score均为23,EScore均为9,但DScore不同,因此排名不同):

   DScore  EScore  Total Score  Rank
0       2       6           17     3
1       2       7           15     4
2       4       9           23     2
3       4       9           23     2
4       5      10           25     1
登录后复制

注:上述期望结果与原始问题略有差异,已根据问题描述的逻辑进行了修正,以更好地体现多级破平器的作用。例如,如果DScore: [2, 2, 4, 4, 5], EScore: [6, 7, 9, 9, 10], Total Score: [17, 15, 23, 23, 25],那么索引2和3的Total Score和EScore都相同,此时需要DScore来破平。如果DScore也相同,则它们才获得相同的排名。

解决方案:加权复合分数法

解决此类问题的有效方法是创建一个“复合分数”列。这个复合分数是通过将主排名列与次要排名列(破平器)进行加权求和得到的。关键在于为破平器列分配足够小的权重,以确保它们只在主排名列的值完全相同时才发挥作用。

步骤1:确定排名优先级和权重

  1. 主排名列: 'Total Score' (权重最高)
  2. 第一破平器: 'EScore' (权重次之)
  3. 第二破平器: 'DScore' (权重最低)

为了使破平器仅在主分数相同的情况下生效,我们需要将破平器的权重设置得足够小,使其加到主分数上时,不会改变主分数不同时的相对大小关系。例如,如果主分数相差1,那么破平器的最大可能加权值必须小于1。

步骤2:计算加权复合分数

Weights.gg
Weights.gg

多功能的AI在线创作与交流平台

Weights.gg 3352
查看详情 Weights.gg

我们将'EScore'乘以一个较小的系数(如0.01),将'DScore'乘以一个更小的系数(如0.0001),然后将这些加权值添加到'Total Score'上。

# 原始DataFrame
df = pd.DataFrame({
    "DScore": [2, 2, 4, 4, 5], # 修正DScore以更好地演示破平
    "EScore": [6, 7, 9, 9, 10],
    "Total Score": [17, 15, 23, 23, 25]
})

# 计算加权复合分数
# Total Score 是主排名依据,EScore 是第一破平器,DScore 是第二破平器
# 权重选择:确保EScore的加权值不足以影响Total Score的整数差异
# 确保DScore的加权值不足以影响EScore的加权值差异
df['Composite Score'] = df['Total Score'] + \
                        df['EScore'].mul(0.01) + \
                        df['DScore'].mul(0.0001)

print("\n带有复合分数的DataFrame:")
print(df)
登录后复制

步骤3:使用rank()函数进行排名

有了复合分数后,我们就可以直接对这个复合分数列使用Pandas的rank()函数进行排名。

  • ascending=False: 表示分数越高,排名越靠前(即排名值越小)。
  • method='dense': 这个参数非常重要。它确保了在并列情况下,所有并列项获得相同的排名,并且下一个非并列项的排名是紧接着的整数(例如,1, 2, 2, 3, 4,而不是1, 2, 2, 4, 5)。
  • .astype('int'): 将浮点型的排名结果转换为整数,使之更简洁。
df['Rank'] = df['Composite Score'].rank(ascending=False, method='dense').astype('int')

print("\n最终排名结果DataFrame:")
print(df.drop(columns=['Composite Score'])) # 移除辅助的复合分数列
登录后复制

完整代码示例:

import pandas as pd

# 原始DataFrame
df = pd.DataFrame({
    "DScore": [2, 2, 4, 4, 5],
    "EScore": [6, 7, 9, 9, 10],
    "Total Score": [17, 15, 23, 23, 25]
})

print("原始DataFrame:")
print(df)

# 计算加权复合分数
# 权重选择:0.01 和 0.0001 是示例值,需要根据实际数据范围进行调整
# 目标是确保加权值不会影响更高优先级列的整数差异
df['Composite Score'] = df['Total Score'].add(df['EScore'].mul(0.01)).add(df['DScore'].mul(0.0001))

# 基于复合分数进行排名
df['Rank'] = df['Composite Score'].rank(ascending=False, method='dense').astype('int')

# 打印最终结果,并删除辅助的复合分数列
print("\n最终排名结果DataFrame:")
print(df.drop(columns=['Composite Score']))
登录后复制

输出结果:

原始DataFrame:
   DScore  EScore  Total Score
0       2       6           17
1       2       7           15
2       4       9           23
3       4       9           23
4       5      10           25

最终排名结果DataFrame:
   DScore  EScore  Total Score  Rank
0       2       6           17     3
1       2       7           15     4
2       4       9           23     2
3       4       9           23     2
4       5      10           25     1
登录后复制

从结果可以看出,索引2和3的Total Score和EScore都相同(23和9),但DScore不同(4和4),因此它们获得了相同的排名2。这与我们的预期相符,因为当所有破平器都相同,它们才被视为真正的并列。

注意事项与最佳实践

  1. 权重选择: 示例中的0.01和0.0001是基于假设分数是整数且差异至少为1的情况。在实际应用中,您需要根据数据的具体范围和精度来调整这些权重。
    • 原则: 破平器的最大可能加权值(即破平器列的最大值乘以其权重)必须小于其上一级排名列的最小可能差异。
    • 例如,如果Total Score的最小差异是1,那么EScore的最大值乘以其权重必须小于1。如果EScore的最大值是100,那么其权重应小于0.01。
    • 同样,DScore的最大值乘以其权重,必须小于EScore的最小差异乘以EScore的权重。
  2. method='dense'的重要性: 在需要连续排名的场景中,dense方法是理想选择,它避免了排名中的空缺。如果需要其他并列处理方式(如平均排名、最小排名等),可以查阅rank()函数的其他method参数选项。
  3. 性能考虑: 对于非常大的数据集,创建额外的辅助列会增加内存消耗。然而,对于大多数常见的数据集大小,这种方法的性能是可接受的。
  4. 可读性: 这种方法通过显式创建复合分数,使得排名逻辑非常清晰和易于理解。

总结

通过创建加权复合分数,并结合Pandas rank()函数的强大功能,我们可以优雅地解决DataFrame中基于多列条件进行排名和处理并列情况的复杂需求。这种方法不仅灵活,而且易于理解和实现,是数据分析师处理复杂排名问题的有力工具。理解权重的选择原则是成功应用此方法的关键。

以上就是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号