Python pandas忽略NaN值将所有重复行拆分至新DataFrame的方法
问题说明
现有一个DataFrame,其Animals列存在重复值,需求为:忽略NaN空值做重复判定,当Animals列的非NaN值出现重复时,将所有重复值对应的行拆分到新的DataFrame中,原有实现无法正确完成提取逻辑。
输入示例DataFrame:
Animals Stuff 0 Cow red 1 NaN blue 3 123 green 4 Cow green 5 NaN 1235 6 Dog 1235 7 123 red
期望输出两个DataFrame:
- df1(非重复行集合,包含所有NaN行、仅出现一次的有效值行):
Animals Stuff 1 NaN blue 5 NaN 1235 6 Dog 1235
- df2(所有重复行集合,仅统计非NaN值的重复情况):
Animals Stuff 0 Cow red 4 Cow green 3 123 green 7 123 red
原有实现代码:
duplicated = df['Animals'].duplicated(keep=False) & ~df['Animals'].isna() dupes = df[duplicated] data = df[~duplicated] dupes.to_csv("Path/DuplicateAnimals.csv", index = False) data.to_csv("Path/data.csv", index = False)
实现方案
原有写法依赖duplicated对NaN的默认处理逻辑,在部分pandas版本或特殊数据类型场景下会出现判定偏差,用值计数的方式实现逻辑更稳定可控,步骤如下:
- 统计
Animals列非空值的出现频次,筛选出出现次数大于1的重复值集合 - 生成重复行掩码:非空且值属于重复值集合的行标记为True
- 用掩码拆分两个DataFrame即可
完整可运行代码:
import pandas as pd import numpy as np # 构造示例数据 df = pd.DataFrame({ 'Animals': ['Cow', np.nan, '123', 'Cow', np.nan, 'Dog', '123'], 'Stuff': ['red', 'blue', 'green', 'green', '1235', '1235', 'red'] }, index=[0,1,3,4,5,6,7]) # 统计非空值的出现次数 value_counts = df['Animals'].dropna().value_counts() # 筛选出出现次数>=2的重复值 dup_values = value_counts[value_counts >= 2].index # 生成重复行掩码:非空 且 值在重复值列表中 is_dup = df['Animals'].notna() & df['Animals'].isin(dup_values) # 拆分两个df df2 = df[is_dup] # 重复行集合 df1 = df[~is_dup] # 非重复行集合 # 导出文件 df2.to_csv("Path/DuplicateAnimals.csv", index=False) df1.to_csv("Path/data.csv", index=False)
运行后得到的df1和df2和期望输出完全一致,该写法不会把任意数量的NaN判定为重复值,符合需求。
内容的提问来源于stack exchange,提问作者feelsgood
相关产品推荐
相关产品推荐

