Pandas按行处理指定列子集:仅重复≥3次时去重保留首项
高效处理百万级DataFrame中重复值(仅删除出现≥3次的重复项)
问题背景
处理约700万行的Pandas DataFrame,需在指定列子集内,仅对出现3次及以上的重复数值做去重处理(保留首次出现的列),出现2次的重复值不做修改。
示例数据
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': [np.nan, 75.51, 24220.34], 'x7': [np.nan, np.nan, np.nan], 'v': [np.nan, np.nan, np.nan], 'y': [404.29, np.nan, 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)
需求说明
- 仅针对指定列子集操作:
x3、x4、x5、x6、x7、v、y、ay、by、cy、gy、uap、ubp - 同一行内,若某个数值出现3次及以上重复,删除后续重复项,保留首次出现的列
- 出现2次的重复值(如示例第二行的
75.33)不做任何修改
原有方案的问题
此前使用的代码会误删仅出现2次的重复值,且逻辑不符合需求:
check = ['x3', 'x4', 'x5', 'x6', 'x7', 'v', 'y', 'ay', 'by', 'cy', 'gy', 'uap', 'ubp'] df.loc[:, check] = df.loc[:, check].mask(df.loc[:, check].apply(pd.Series.duplicated, axis=1))
这段代码会标记所有非首次出现的重复值(包括2次的)并删除,比如示例中第二行的75.33会被误删,同时逐行apply的方式对700万行数据效率极低。
高效解决方案
采用向量化操作实现需求,避免逐行循环,适配百万级数据量:
check_cols = ['x3', 'x4', 'x5', 'x6', 'x7', 'v', 'y', 'ay', 'by', 'cy', 'gy', 'uap', 'ubp'] subset = df[check_cols] # 计算每行内各数值的出现次数 row_value_counts = subset.apply(lambda row: row.value_counts(), axis=1).fillna(0) # 将次数映射回原子集的每个位置 value_counts_matrix = subset.apply(lambda row: row.map(row_value_counts.loc[row.name]), axis=1) # 标记需要掩盖的位置:非首次出现 且 出现次数≥3 mask_condition = subset.duplicated(axis=1) & (value_counts_matrix >= 3) # 应用掩盖规则,仅删除符合条件的重复项 df[check_cols] = subset.mask(mask_condition) print(df)
代码解释
- 计算行内数值计数:通过
apply(lambda row: row.value_counts(), axis=1)统计每行中每个数值的出现次数,得到每行的计数Series - 映射计数到原矩阵:将每行的计数映射回原列子集的对应位置,形成一个与子集形状一致的矩阵,每个位置存储对应数值在该行的出现次数
- 生成掩盖条件:结合
duplicated(axis=1)(标记非首次出现的位置)和value_counts_matrix >=3(标记出现次数≥3的数值),得到需要设为NaN的位置 - 应用掩盖:用
mask方法将符合条件的位置设为NaN,完成去重
该方案全程使用Pandas向量化操作,避免了低效的逐行循环,能够高效处理700万行级别的数据。
内容的提问来源于stack exchange,提问作者anarchy
相关产品推荐
相关产品推荐

