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

Pandas中基于列条件去除重复行的实现及进阶需求

问题描述

现有一个包含Action(取值为"start"、"end")、points(整数)、cards(整数)列的Pandas DataFrame,数据如下:

Action  points  cards
start   1       1
start   2       2
start   2       3
end     1       1
end     2       2
end     2       3

需求:仅当Action等于"start"时,去除points值重复的行,期望输出如下:

Action  points  cards
start   1       1
start   2       2
end     1       1
end     2       2
end     2       3

尝试以下命令均无效:

df[df["action"] == "start"].drop_duplicates(["points"]) # 无效果,未将结果赋值回原DataFrame
df[df["action"] == "start"].drop_duplicates(["points"], inplace=True) # 报错,切片返回视图而非副本,无法原地修改
df[df["action"] == "start"] = df[df["action"] == "start"].drop_duplicates(["points"]) # 新增NaN行,左右两边索引不匹配

核心问题

  1. 在不能使用dropna()的情况下,该如何实现需求?
  2. 附加问题:若希望去除(start, 2, 2)行而非(start, 2, 3)行,该如何操作?
解决方案

一、主问题实现(保留start组内points首次出现的行)

方法1:拆分数据后拼接(直观易懂)

将start和end数据分开处理,对start组去重后再与end组合并:

import pandas as pd

# 构造原始数据
data = {
    "Action": ["start", "start", "start", "end", "end", "end"],
    "points": [1, 2, 2, 1, 2, 2],
    "cards": [1, 2, 3, 1, 2, 3]
}
df = pd.DataFrame(data)

# 处理start数据:按points去重,保留第一个出现的行
start_df = df[df["Action"] == "start"].drop_duplicates(subset=["points"], keep="first")
# 保留所有end数据
end_df = df[df["Action"] == "end"]
# 合并并恢复原始索引顺序
result_df = pd.concat([start_df, end_df]).sort_index()
print(result_df)

方法2:布尔索引筛选(高效简洁)

通过分组标记需要保留的行,无需拆分数据:

# 标记start组内points首次出现的行,end组全部保留
keep_mask = df.groupby(["Action", "points"]).cumcount() == 0
result_df = df[(df["Action"] == "end") | keep_mask]
print(result_df)

二、附加问题实现(保留start组内points最后出现的行)

只需修改去重时的keep参数为"last",或调整布尔索引的标记逻辑:

方法1:拆分拼接+keep="last"

start_df = df[df["Action"] == "start"].drop_duplicates(subset=["points"], keep="last")
end_df = df[df["Action"] == "end"]
result_df = pd.concat([start_df, end_df]).sort_index()
print(result_df)

方法2:布尔索引标记最后一行

# 计算每个(Action, points)组的行数
group_size = df.groupby(["Action", "points"]).transform("size")
# 标记end组全部行,或start组内的最后一行
keep_mask = (df["Action"] == "end") | (df.groupby(["Action", "points"]).cumcount() == group_size - 1)
result_df = df[keep_mask]
print(result_df)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 17:27:30