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

按行处理DataFrame指定列:仅当所有列值重复时保留首个副本

解决方案:按行处理指定列子集,仅当所有值相同时去重保留首个

这是此前两个技术问题的扩展:按行删除指定列子集的重复项仅保留首个副本、按行删除指定列子集的重复项仅当重复数≥3时保留首个副本。现有一个约700万行的DataFrame,示例代码如下:

import pandas as pd
import numpy as np

data = {'date': ['2023-02-22', '2023-02-21', '2023-02-23'],
        'x1': ['descx1a', 'descx1b', 'descx1c'],
        'x2': ['ALSFNHF950', 'KLUGUIF615', np.nan],
        'x3': [np.nan, np.nan, 24319.4],
        'x4': [np.nan, np.nan, 24334.15],
        'x5': [np.nan, np.nan, 24040.11],
        'x6': [404.29, 75.21, 24220.34],
        'x7': [np.nan, np.nan, np.nan],
        'v': [np.nan, np.nan, np.nan],
        'y': [404.29, 75.33, np.nan],
        'ay': [np.nan, np.nan, np.nan],
        'by': [np.nan, np.nan, np.nan],
        'cy': [np.nan, np.nan, np.nan],
        'gy': [np.nan, np.nan, np.nan],
        'uap': [404.29, 75.33, np.nan],
        'ubp': [404.29, 75.33, np.nan],
        'sf': [np.nan, 2.0, np.nan]}

df = pd.DataFrame(data)

需求说明

仅当指定列子集中的所有列值完全相同时,删除重复项并仅保留首个副本;若子集内仅部分列值重复,则不做处理。

例如指定列子集为['x6', 'y', 'uap', 'ubp']时,输出结果如下:

# 输出的DataFrame对应数据
data = {'date': ['2023-02-22', '2023-02-21', '2023-02-23'],
        'x1': ['descx1a', 'descx1b', 'descx1c'],
        'x2': ['ALSFNHF950', 'KLUGUIF615', np.nan],
        'x3': [np.nan, np.nan, 24319.4],
        'x4': [np.nan, np.nan, 24334.15],
        'x5': [np.nan, np.nan, 24040.11],
        'x6': [404.29, 75.21, 24220.34],
        'x7': [np.nan, np.nan, np.nan],
        'v': [np.nan, np.nan, np.nan],
        'y': [np.nan, 75.33, np.nan],
        'ay': [np.nan, np.nan, np.nan],
        'by': [np.nan, np.nan, np.nan],
        'cy': [np.nan, np.nan, np.nan],
        'gy': [np.nan, np.nan, np.nan],
        'uap': [np.nan, 75.33, np.nan],
        'ubp': [np.nan, 75.33, np.nan],
        'sf': [np.nan, 2.0, np.nan]}

实现代码

针对700万行的大数据量,采用矢量化操作保证效率,避免逐行循环:

# 指定需要处理的列子集
subset = ['x6', 'y', 'uap', 'ubp']

# 提取子集数据
subset_df = df[subset]

# 1. 筛选出需要处理的行:所有非NaN值完全相同,且不是全NaN的行
# 获取每行第一个非NaN值(处理开头有NaN的情况)
first_non_nan = subset_df.bfill(axis=1).iloc[:, 0]
# 检查每行所有值是否与第一个非NaN值一致
all_values_same = (subset_df == first_non_nan[:, None]).all(axis=1)
# 排除全NaN的行
all_nan_rows = subset_df.isna().all(axis=1)
# 最终需要处理的行掩码
process_mask = all_values_same & ~all_nan_rows

# 2. 创建替换掩码:仅保留每行第一个列的值,其余列设为NaN(仅在需要处理的行生效)
replace_mask = pd.DataFrame(False, index=subset_df.index, columns=subset_df.columns)
replace_mask.iloc[:, 0] = True  # 第一列保留原值
# 不需要处理的行,所有列都保留原值
replace_mask = replace_mask | ~process_mask[:, None]

# 3. 应用掩码处理子集列
processed_subset = subset_df.where(replace_mask)

# 4. 将处理后的子集列替换回原DataFrame
df[subset] = processed_subset

# 查看结果
print(df)

代码说明

  • 矢量化判断:通过bfill和广播操作快速判断每行所有值是否一致,避免逐行循环,适合大数据量
  • 掩码控制:通过双层掩码精准控制需要替换的位置,确保只有符合条件的行才会被处理
  • 无侵入修改:仅修改指定列子集,原DataFrame的其他列保持不变

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 01:59:58