Python Pandas实现行级补充压制:确保每行至少2个压制值
解决思路与实现方案
你的思路完全可行,在Pandas里可以轻松实现。下面提供两种方案,分别适合不同场景:
方案一:逐行处理(贴合你的初始思路,易理解)
这种方法通过apply逐行遍历数据,完全匹配你“找最小非-1值、替换第一个出现的该值”的逻辑,适合刚接触Pandas的阶段快速上手:
import pandas as pd # 初始化数据 data = {'group':['group1','group2','group3','group4'], 'cat1':[0,-1,-1,-1], 'cat2':[-1,22,14,-1], 'cat3':[0,0,-1,0], 'sup_cnt':[1,1,2,3]} df = pd.DataFrame(data) # 定义需要处理的分类列 cat_cols = ['cat1', 'cat2', 'cat3'] # 编写单行处理函数 def process_single_row(row): # 提取当前行的分类列数据 category_vals = row[cat_cols] # 筛选出非-1的数值 non_suppressed = category_vals[category_vals != -1] # 如果没有可替换的数值,直接返回原行 if non_suppressed.empty: return row # 找到最小的非压制值 min_val = non_suppressed.min() # 定位第一个出现该最小值的列 first_min_col = non_suppressed[non_suppressed == min_val].index[0] # 替换为-1 row[first_min_col] = -1 return row # 对sup_cnt=1的行应用处理函数,其他行保持不变 df = df.apply(lambda x: process_single_row(x) if x['sup_cnt'] == 1 else x, axis=1) print(df)
方案二:向量化处理(高效适配大数据量)
如果你的数据集很大,逐行处理效率会偏低,这种向量化方法利用Pandas的矩阵运算特性,速度更快:
import pandas as pd # 初始化数据 data = {'group':['group1','group2','group3','group4'], 'cat1':[0,-1,-1,-1], 'cat2':[-1,22,14,-1], 'cat3':[0,0,-1,0], 'sup_cnt':[1,1,2,3]} df = pd.DataFrame(data) cat_cols = ['cat1', 'cat2', 'cat3'] df_processed = df.copy() # 筛选需要处理的行(sup_cnt=1) mask = df_processed['sup_cnt'] == 1 # 计算每行非-1数值的最小值(用NaN替代-1后取最小) min_values = df_processed[cat_cols].where(df_processed[cat_cols] != -1).min(axis=1) # 构造布尔矩阵:标记每行中等于最小值且非-1的位置 bool_matrix = (df_processed[cat_cols] == min_values[:, None]) & (df_processed[cat_cols] != -1) # 找到每行第一个符合条件的列名 first_min_columns = bool_matrix.idxmax(axis=1) # 批量替换目标值 for idx in df_processed[mask].index: target_col = first_min_columns[idx] df_processed.loc[idx, target_col] = -1 print(df_processed)
两种方案运行后都会得到你期望的结果:
group cat1 cat2 cat3 sup_cnt 0 group1 -1 -1 0 1 1 group2 -1 22 -1 1 2 group3 -1 14 -1 2 3 group4 -1 -1 0 2
内容的提问来源于stack exchange,提问作者s_bklyn
相关产品推荐
相关产品推荐

