You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于条件移除分组低排名行的Pandas数据处理问题

问题描述

原始电影DataFrame如下:

Index  Movie                   Rotten Tomato Score  Director             Ranking
1      Batman Rises            87                   Christopher Nolan    1
2      Interstellar            73                   Christopher Nolan    2
3      Legally Blonde          71                   Robert Luketic       1
4      The Ugly Truth          14                   Robert Luketic       2
5      (500) Days of Summer    85                   Marc Webb            1
6      The Amazing Spider-Man  71                   Marc Webb            2
7      Wide Awake              45                   M N Shyamalan        1
8      The Last Airbender       5                   M N Shyamalan        2

需求规则:

  • 按导演分组后,若组内排名第1的电影烂番茄得分高于50(即>50%),仅保留该组内排名第1的电影
  • 若组内排名第1的得分≤50,保留该组所有电影

理想结果:

Index  Movie                 Rotten Tomato Score  Director             Ranking  
    1  Batman Rises          87                   Christopher Nolan    1      
    3  Legally Blonde        71                   Robert Luketic       1
    5  (500) Days of Summer  85                   Marc Webb            1
    7  Wide Awake            45                   M N Shyamalan        1
    8  The Last Airbender    5                    M N Shyamalan        2

尝试的错误代码:

movie_names = movie_names.groupby('Movie').filter(lambda g: (g.score <= 0.5).any())

这段代码错误移除了M N Shyamalan的所有电影,求正确实现方式。

解决方案

你的代码存在两个核心问题:

  1. 分组依据错误:应该按Director分组,而非Movie
  2. 得分判断逻辑错误:烂番茄得分是整数形式的百分比(比如87代表87%),你用了0.5(对应0.5%),完全不符合实际规则;同时筛选逻辑也和需求不符。

这里提供两种简洁的实现方式:

方法1:使用groupby.filter

filtered_movies = movie_names.groupby('Director').filter(
    lambda g: 
    # 情况1:组内第一名得分>50,仅保留排名1的行
    ((g[g['Ranking'] == 1]['Rotten Tomato Score'].iloc[0] > 50) & (g['Ranking'] == 1)).any()
    # 情况2:组内第一名得分≤50,保留所有行
    or (g[g['Ranking'] == 1]['Rotten Tomato Score'].iloc[0] <= 50)
)

方法2:用transform广播组内第一名得分,再筛选

这种方法逻辑更清晰,便于调试:

# 计算每个导演组内排名第1的电影得分,广播到组内所有行
first_rank_score = movie_names.groupby('Director')['Rotten Tomato Score'].transform(
    lambda x: x[movie_names.loc[x.index, 'Ranking'] == 1].iloc[0]
)

# 按需求筛选:要么第一名得分>50且当前行排名1,要么第一名得分≤50
filtered_movies = movie_names[
    ((first_rank_score > 50) & (movie_names['Ranking'] == 1)) | (first_rank_score <= 50)
]

运行任意一种方法后,就能得到你想要的结果。

内容的提问来源于stack exchange,提问作者ds_1234

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 14:12:33