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

如何快速移除Pandas DataFrame重复索引及保留首个非NaN值的重复行?

Pandas DataFrame去重问题解答

我来帮你搞定这两个Pandas去重问题,都是日常数据处理里很常见的场景:

1. 如何快速移除Pandas DataFrame中的重复索引?

要高效删掉重复索引,直接利用Pandas索引的duplicated()方法就好——它会生成一个布尔数组,标记出哪些索引是重复的(默认从第二个重复项开始标记为True)。我们只需要对这个数组取反,就能筛选出只含唯一索引的行:

import pandas as pd
import numpy as np

# 构造带重复索引的示例DataFrame
df = pd.DataFrame({'value': [10, 20, 30, 40]}, index=['x', 'x', 'y', 'z'])

# 移除重复索引,保留首次出现的行
df_cleaned = df[~df.index.duplicated()]
# 用loc写法更直观,效果一样
# df_cleaned = df.loc[~df.index.duplicated()]

print(df_cleaned)

这个方法是矢量化操作,没有循环,处理大型数据集速度也很快,是最推荐的方式。

2. 如何高效移除Pandas DataFrame中的重复行,且始终保留首个非NaN值?

看你提供的示例数据,核心需求应该是按重复的索引分组,每个分组里的每一列都保留第一个出现的非NaN值,同时去掉重复的行。这里用groupby结合自定义聚合函数就能完美实现:

首先先看你的原始数据:

import pandas as pd
import numpy as np
data = pd.DataFrame({'a': [np.nan,np.nan,2,2,3,3,5], 'b': [2,1,1,1,np.nan,2,1]}, index=[pd.Timestamp('2018-03-01'), pd.Timestamp('2018-03-02'), pd.Timestamp('2018-03-02'), pd.Timestamp('2018-03-02'), pd.Timestamp('2018-03-03'), pd.Timestamp('2018-03-03'), pd.Timestamp('2018-03-04')])
print(data)

输出如下:

a    b

2018-03-01 NaN 2.0
2018-03-02 NaN 1.0
2018-03-02 2.0 1.0
2018-03-02 2.0 1.0
2018-03-03 3.0 NaN
2018-03-03 3.0 2.0
2018-03-04 5.0 1.0

接下来是处理步骤:我们按索引分组,对每一列应用一个函数,取出第一个非NaN值(如果列里全是NaN就保留NaN):

# 自定义函数:提取序列中的第一个非NaN值
def get_first_non_nan(series):
    non_nan_values = series.dropna()
    return non_nan_values.iloc[0] if not non_nan_values.empty else np.nan

# 按索引分组并聚合
cleaned_data = data.groupby(data.index).agg(get_first_non_nan)

print(cleaned_data)

处理后的输出:

a    b

2018-03-01 NaN 2.0
2018-03-02 2.0 1.0
2018-03-03 3.0 2.0
2018-03-04 5.0 1.0

如果你想写得更简洁,也可以用bfill()(向后填充NaN)结合取每组第一行的方式,效果完全一致:

cleaned_data = data.groupby(data.index).apply(lambda x: x.bfill().iloc[0])

这个写法更短,效率也不错,适合大部分场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:40:48