0

0

使用 Pandas 根据排名查找和过滤 DataFrame 数据

DDD

DDD

发布时间:2025-10-30 11:38:49

|

854人浏览过

|

来源于php中文网

原创

使用 Pandas 根据排名查找和过滤 DataFrame 数据

本教程将详细介绍如何利用 pandas 库高效地处理两个 dataframe,实现根据指定列(`smth`)的排名信息(来源于 `df2`)对另一个主 dataframe(`df1`)进行过滤。核心思路是为 `df1` 中的每个唯一 `code`,找出其关联的 `smth` 中排名最低的行。我们将通过字典映射、`groupby` 和 `idxmin` 方法,避免传统循环,实现高性能的数据筛选。

在数据分析和处理中,我们经常会遇到需要根据某个外部参照表中的排名或优先级信息来筛选主数据表的情况。例如,给定一个包含多个产品代码(code)及其相关属性(如 smth)的 DataFrame,以及另一个定义了 smth 类型及其对应排名的 DataFrame,我们的目标是为每个产品代码,仅保留其所有 smth 类型中排名最低(优先级最高)的那一行数据。本教程将展示如何使用 Pandas 库以一种高效、简洁的方式完成这一任务。

1. 数据准备

首先,我们需要创建示例 DataFrames df1 和 df2,它们模拟了实际场景中的数据结构。

df1 包含主数据,其中 code 列用于分组,smth 列是需要根据排名进行比较的字段。 df2 包含 smth 类型及其对应的 rank。rank 值越小,表示优先级越高。

import pandas as pd

# 主数据 DataFrame (df1)
data1 = {'smth': ['RB', 'Supp', 'DX RT', 'Fk', 'CZFO', 'Supp_t', 'RK', 'rec', 'commerc', 'Supp_t'],
         'code': ['HC-1343958', 'HC-1343958', 'HC-1340305', 'HC-1340305', 'HC-1107001', 'HC-1107001', 'HC-1107001', 'HC-1135154', 'HC-1135154', 'HC-1135154'],
         'product_name': ['ERXY3-400', 'ERXY3-400', 'BWH/S 100 Level PRO', 'BWH/S 100 Level PRO', 'GWH 12 Fonte', 'GWH 12 Fonte', 'GWH 12 Fonte', 'BEC/ETER-1500', 'BEC/ETER-1503', 'BEC/ETER-1505'],
         'digit': [3, 2, 20, 1, 1, 17, 78, 246, 10, 23],
         'changes': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]}
df1 = pd.DataFrame(data1)

# 排名参照 DataFrame (df2)
data2 = {'smth': ['rec', 'Supp', 'Supp_t', 'RK', 'CZFO', 'RB'], 'rank': [2, 4, 6, 8, 9, 10]}
df2 = pd.DataFrame(data2)

print("df1:")
print(df1)
print("\ndf2:")
print(df2)

df1 示例输出:

       smth        code         product_name  digit  changes
0        RB  HC-1343958            ERXY3-400      3        1
1      Supp  HC-1343958            ERXY3-400      2        1
2     DX RT  HC-1340305  BWH/S 100 Level PRO     20        1
3        Fk  HC-1340305  BWH/S 100 Level PRO      1        1
4      CZFO  HC-1107001         GWH 12 Fonte      1        1
5    Supp_t  HC-1107001         GWH 12 Fonte     17        1
6        RK  HC-1107001         GWH 12 Fonte     78        1
7       rec  HC-1135154        BEC/ETER-1500    246        1
8   commerc  HC-1135154        BEC/ETER-1503     10        1
9    Supp_t  HC-1135154        BEC/ETER-1505     23        1

df2 示例输出:

     smth  rank
0     rec     2
1    Supp     4
2  Supp_t     6
3      RK     8
4    CZFO     9
5      RB    10

2. 解决方案:使用 Pandas 映射、分组和索引查找

解决此问题的关键在于将 df2 中的排名信息有效地应用到 df1,然后根据 code 进行分组,并找到每个组中具有最低排名的行。

步骤 2.1: 创建 smth 到 rank 的映射字典

为了高效地查找 smth 对应的 rank,我们将 df2 转换为一个字典。字典的键是 smth,值是 rank。

m = dict(df2[['smth', 'rank']].values)
print("映射字典 m:")
print(m)

输出:

映射字典 m:
{'rec': 2, 'Supp': 4, 'Supp_t': 6, 'RK': 8, 'CZFO': 9, 'RB': 10}

步骤 2.2: 将排名信息映射到 df1

使用 df1['smth'].map(m) 将 df1 中 smth 列的值替换为它们在字典 m 中对应的排名。如果 df1 中存在 smth 值不在 m 中,map 函数将默认填充 NaN。

df1_ranks = df1['smth'].map(m)
print("\ndf1 映射后的排名系列:")
print(df1_ranks)

输出:

df1 映射后的排名系列:
0    10.0
1     4.0
2     NaN
3     NaN
4     9.0
5     6.0
6     8.0
7     2.0
8     NaN
9     6.0
Name: smth, dtype: float64

可以看到,DX RT, Fk, commerc 这些 smth 值在 df2 中没有对应的排名,因此被映射为 NaN。

Med-PaLM
Med-PaLM

来自 Google Research 的大型语言模型,专为医学领域设计。

下载

步骤 2.3: 按 code 分组并找到最低排名的行索引

现在,我们将 df1 按 code 列进行分组,并在每个组内,找到 df1_ranks 系列中值最小(即排名最低)的行的原始索引。groupby().idxmin() 方法非常适合此目的。它返回一个 Series,其索引是 code 值,值是 df1 中对应最低排名行的原始索引。

idxmin_indices = df1_ranks.groupby(df1['code']).idxmin()
print("\n每个 code 组中最低排名行的原始索引:")
print(idxmin_indices)

输出:

每个 code 组中最低排名行的原始索引:
code
HC-1107001    5
HC-1135154    7
HC-1340305    2
HC-1343958    1
Name: smth, dtype: int64

例如,对于 HC-1107001,其最低排名行在 df1 中的原始索引是 5。

步骤 2.4: 使用索引过滤 df1

最后,我们使用 idxmin_indices 中包含的原始索引来从 df1 中选择所需的行。df1.index.isin(idxmin_indices) 会生成一个布尔系列,用于筛选 df1。

out = df1[df1.index.isin(idxmin_indices)]
print("\n最终结果 DataFrame (out):")
print(out)

最终结果输出:

     smth        code    product_name  digit  changes
1    Supp  HC-1343958       ERXY3-400      2        1
2   DX RT  HC-1340305  BWH/S 100 Level PRO     20        1
5  Supp_t  HC-1107001         GWH 12 Fonte     17        1
7     rec  HC-1135154        BEC/ETER-1500    246        1

结果分析: 让我们以 code 为 HC-1343958 为例:

  • df1 中有两行:索引 0 (smth='RB', rank=10) 和索引 1 (smth='Supp', rank=4)。
  • idxmin_indices 为 HC-1343958 找到的索引是 1,因为 Supp 的排名 4 低于 RB 的排名 10。
  • 因此,最终结果 out 中保留了索引为 1 的行。

对于 HC-1340305:

  • df1 中有两行:索引 2 (smth='DX RT', rank=NaN) 和索引 3 (smth='Fk', rank=NaN)。
  • 当 groupby().idxmin() 遇到 NaN 值时,它会选择第一个非 NaN 值。如果所有值都是 NaN,它会选择第一个 NaN 值的索引。在这里,DX RT 和 Fk 都没有排名,它们都被映射为 NaN。idxmin 在遇到多个相同最小值(包括 NaN)时,会返回第一个出现的索引。因此,它选择了索引 2。

3. 完整代码示例

将上述步骤整合到一起,得到完整的解决方案代码:

import pandas as pd

# 1. 数据准备
data1 = {'smth': ['RB', 'Supp', 'DX RT', 'Fk', 'CZFO', 'Supp_t', 'RK', 'rec', 'commerc', 'Supp_t'],
         'code': ['HC-1343958', 'HC-1343958', 'HC-1340305', 'HC-1340305', 'HC-1107001', 'HC-1107001', 'HC-1107001', 'HC-1135154', 'HC-1135154', 'HC-1135154'],
         'product_name': ['ERXY3-400', 'ERXY3-400', 'BWH/S 100 Level PRO', 'BWH/S 100 Level PRO', 'GWH 12 Fonte', 'GWH 12 Fonte', 'GWH 12 Fonte', 'BEC/ETER-1500', 'BEC/ETER-1503', 'BEC/ETER-1505'],
         'digit': [3, 2, 20, 1, 1, 17, 78, 246, 10, 23],
         'changes': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]}
df1 = pd.DataFrame(data1)

data2 = {'smth': ['rec', 'Supp', 'Supp_t', 'RK', 'CZFO', 'RB'], 'rank': [2, 4, 6, 8, 9, 10]}
df2 = pd.DataFrame(data2)

print("原始 df1:")
print(df1)
print("\n原始 df2:")
print(df2)

# 2. 解决方案核心逻辑
# 2.1 创建 smth 到 rank 的映射字典
m = dict(df2[['smth', 'rank']].values)

# 2.2 将排名信息映射到 df1 的 smth 列
# 注意:如果 df1 中有 smth 不在 df2 中,映射结果会是 NaN
mapped_ranks = df1['smth'].map(m)

# 2.3 按 'code' 分组,并找到每个组中最低排名的行索引
# idxmin() 返回的是原始 df1 中的行索引
idxmin_indices = mapped_ranks.groupby(df1['code']).idxmin()

# 2.4 使用这些索引过滤 df1
# 注意:idxmin_indices 是一个 Series,其值是 df1 的索引。
# 使用 df1.index.isin(idxmin_indices) 来进行布尔索引。
out = df1[df1.index.isin(idxmin_indices)]

print("\n最终结果 DataFrame:")
print(out)

4. 注意事项与优化

  1. 处理缺失排名(NaN):
    • 如果 df1 中的 smth 值在 df2 中没有对应排名,map 操作会生成 NaN。idxmin() 默认会忽略 NaN 值,只在非 NaN 值中寻找最小值。如果一个 code 组中的所有 smth 值都没有排名(都是 NaN),idxmin() 会返回该组中第一个 NaN 值的索引。
    • 如果希望排除所有没有排名的行,可以在 mapped_ranks 上应用 dropna() 或在过滤前添加条件。例如,idxmin_indices = mapped_ranks.dropna().groupby(df1['code']).idxmin()。
  2. 性能:
    • 此方法避免了显式的 for 循环,充分利用了 Pandas 的向量化操作,因此在大数据集上具有优异的性能。
    • 创建映射字典 m 是一种高效的查找方式,比每次循环查询 DataFrame 更快。
  3. 多重最低排名:
    • 如果一个 code 组中存在多个 smth 值具有相同的最低排名,idxmin() 会返回这些具有最低排名的行中,在原始 df1 中最先出现的那个行的索引。如果需要保留所有具有最低排名的行,则需要使用不同的方法,例如先 groupby 后 transform('min') 得到每个组的最低排名,然后进行条件筛选。

5. 总结

本教程展示了如何使用 Pandas 的 map()、groupby() 和 idxmin() 组合功能,高效地根据外部排名信息筛选 DataFrame。这种方法不仅代码简洁,而且在处理大规模数据时表现出卓越的性能。理解这些核心 Pandas 函数的用法,是进行复杂数据操作的关键。通过灵活运用这些工具,可以解决各种数据筛选和转换的挑战。

相关专题

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

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

48

2025.12.04

treenode的用法
treenode的用法

​在计算机编程领域,TreeNode是一种常见的数据结构,通常用于构建树形结构。在不同的编程语言中,TreeNode可能有不同的实现方式和用法,通常用于表示树的节点信息。更多关于treenode相关问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

529

2023.12.01

C++ 高效算法与数据结构
C++ 高效算法与数据结构

本专题讲解 C++ 中常用算法与数据结构的实现与优化,涵盖排序算法(快速排序、归并排序)、查找算法、图算法、动态规划、贪心算法等,并结合实际案例分析如何选择最优算法来提高程序效率。通过深入理解数据结构(链表、树、堆、哈希表等),帮助开发者提升 在复杂应用中的算法设计与性能优化能力。

1

2025.12.22

golang map内存释放
golang map内存释放

本专题整合了golang map内存相关教程,阅读专题下面的文章了解更多相关内容。

73

2025.09.05

golang map相关教程
golang map相关教程

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

23

2025.11.16

golang map原理
golang map原理

本专题整合了golang map相关内容,阅读专题下面的文章了解更多详细内容。

36

2025.11.17

java判断map相关教程
java判断map相关教程

本专题整合了java判断map相关教程,阅读专题下面的文章了解更多详细内容。

31

2025.11.27

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

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

447

2023.07.04

苹果官网入口直接访问
苹果官网入口直接访问

苹果官网直接访问入口是https://www.apple.com/cn/,该页面具备0.8秒首屏渲染、HTTP/3与Brotli加速、WebP+AVIF双格式图片、免登录浏览全参数等特性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

10

2025.12.24

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Git 教程
Git 教程

共21课时 | 2.2万人学习

Git版本控制工具
Git版本控制工具

共8课时 | 1.5万人学习

Git中文开发手册
Git中文开发手册

共0课时 | 0人学习

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

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