如何让drop_duplicates将NaN视为不同值以保留指定数据?
解决drop_duplicates将NaN视为不同值的问题
没问题!默认情况下pandas确实会把所有NaN值视为相等的,所以用drop_duplicates(subset=['the_key'])时会把它们当成重复项处理。要实现把每个NaN都看作唯一值、保留所有NaN行的需求,有两种实用的方法:
方法一:用行索引填充NaN(简洁版)
利用行索引的唯一性,把每个NaN替换成对应的行索引,这样每个NaN就变成了唯一值,去重时自然会保留所有NaN行:
import pandas as pd import numpy as np # 构造你提供的示例数据 df = pd.DataFrame({ 'the_key': [np.nan, np.nan, 111, 111], 'C': ['*', '', '*', ''], 'D': ['*', '*', '*', ''] }) # 核心操作:用索引填充NaN后作为去重依据 result = df.drop_duplicates(subset=df['the_key'].fillna(df.index)) print(result)
运行后得到的结果正好符合你要的D列预期:
| 行号 | the_key | C | D |
|---|---|---|---|
| 1 | NaN | * | * |
| 2 | NaN | * | |
| 3 | 111 | * | * |
方法二:给NaN生成唯一序号(稳妥版)
如果你的DataFrame存在重复行索引(虽然不推荐这种情况),可以用分组计数的方式给每个NaN生成唯一序号,避免索引重复带来的问题:
# 给NaN创建唯一标识的临时列 df['temp_unique'] = np.where( df['the_key'].isna(), # 对NaN分组后生成连续序号,确保每个NaN的标识唯一 df.groupby(df['the_key'].isna()).cumcount(), df['the_key'] # 非NaN值保持原样 ) # 基于临时列去重后删除临时列 result = df.drop_duplicates(subset=['temp_unique']).drop('temp_unique', axis=1)
这个方法的逻辑是:把所有NaN行归为一组,用cumcount()给它们分配0、1、2...的唯一序号,这样每个NaN对应的temp_unique值都不同,去重时就会全部保留;而非NaN值则沿用原the_key,重复值会被正常去重。
原理说明
pandas默认将NaN视为相等的(这是遵循SQL的NULL逻辑),所以我们的核心思路就是给每个NaN赋予一个唯一的、不重复的值,让drop_duplicates把它们当成不同的项处理,同时不影响非NaN值的正常去重逻辑。
内容的提问来源于stack exchange,提问作者ifly6
相关产品推荐
相关产品推荐

