基于另一列条件移除某列重复值行——Python/Pandas技术问题
问题描述
我已将CSV文件数据读取为Pandas DataFrame(所有单元格为字符串类型,NaN已替换为""),需要移除特定重复行。
示例输入CSV:
Col1,Col2,Col3 A,rrrrr,fff A,,ffff B,rrr,fffff C,,ffffff D,rrrrrrr,ffff C,rrrr,fffff E,rrrrr,fff C,,kkkkk
需求:移除Col1值重复且Col2值为""的行,期望结果如下:
Col1,Col2,Col3 A,rrrrr,fff B,rrr,fffff D,rrrrrrr,ffff C,rrrr,fffff E,rrrrr,fff
我使用以下代码去重:
my_df = my_df.loc[(my_df["Col2"] != "") | ~my_df["Col1"].duplicated()]
但该代码未能移除所有目标行——若Col2为空的重复行出现在需保留的非空Col2行之前(如Col1为C的情况),该行会被保留,当前输出结果为:
Col1,Col2,Col3 A,rrrrr,fff B,rrr,fffff C,,ffffff D,rrrrrrr,ffff C,rrrr,fffff E,rrrrr,fff
请求教如何修正此问题。
解决方案
原代码的问题在于~my_df["Col1"].duplicated()仅判断当前行是否是Col1的首次出现,所以当空Col2的行是某Col1的首行时,会被错误保留。要解决这个问题,核心是优先保留每个Col1分组中Col2非空的行,再处理重复的空行。
推荐两种高效的解决方法:
方法一:排序后去重(保留原始行顺序)
通过排序让Col2非空的行排在对应Col1分组的前面,再按Col1去重保留首行,最后恢复原始顺序:
# 添加临时列记录原始索引,用于后续恢复顺序 my_df['original_idx'] = my_df.index # 排序规则:先按Col1分组,再让Col2非空的行排在前面 sorted_df = my_df.sort_values(by=['Col1', 'Col2'], ascending=[True, False]) # 按Col1去重,保留每组的第一行(即非空行优先) deduplicated_df = sorted_df.drop_duplicates(subset='Col1', keep='first') # 恢复原始顺序并删除临时列 result_df = deduplicated_df.sort_values(by='original_idx').drop(columns='original_idx')
方法二:分组筛选+合并
先提取所有Col2非空的行,再补充保留那些Col1没有对应非空行的空Col2行(如果需要保留这类数据):
# 提取所有Col2非空的行 non_empty_rows = my_df[my_df["Col2"] != ""] # 获取有非空Col2行的Col1值集合 valid_col1_set = non_empty_rows["Col1"].unique() # 合并结果:保留非空行 + 保留Col1不在有效集合里的空行 result_df = pd.concat([ non_empty_rows, my_df[(my_df["Col2"] == "") & (~my_df["Col1"].isin(valid_col1_set))] ]).drop_duplicates(subset="Col1", keep="first")
两种方法都能得到符合需求的结果,其中方法一更简洁,且能严格保留原始数据的行顺序。
内容的提问来源于stack exchange,提问作者Raits
相关产品推荐
相关产品推荐

