Pandas如何按score差值条件插入行且仅修改新行的score值
解决思路
我们可以通过两种方式实现需求,第一种逻辑直观易调试,适合数据量不大的场景;第二种是向量化实现,处理大量数据时效率更高。
1. 循环实现(易读版)
核心逻辑是遍历所有行,先将当前行加入结果,再判断和下一行的score差值是否满足条件,满足则插入构造的新行即可:
import pandas as pd # 构造原始数据 df1 = pd.DataFrame(data = {'Id': [12345678, 23456789, 34567890, 45678901, 56789012], 'score': [0.0123, 0.0145, 0.0345, 0.5660, 1.0000], 'target': [0, 0, 0, 1, 1]}) res = [] for i in range(len(df1)): # 先加入当前行 res.append(df1.iloc[i].to_dict()) # 非最后一行时判断差值条件 if i < len(df1) - 1: curr_score = df1.loc[i, 'score'] next_score = df1.loc[i+1, 'score'] if abs(next_score - curr_score) >= 0.01: # 构造新行,Id、target取当前行,score取平均值 new_row = { 'Id': df1.loc[i, 'Id'], 'score': (curr_score + next_score) / 2, 'target': df1.loc[i, 'target'] } res.append(new_row) # 转换为DataFrame,重置索引 new_df = pd.DataFrame(res).reset_index(drop=True) print(new_df)
输出结果和你给出的期望完全一致。
2. 向量化实现(高效版)
如果数据量较大,可以用pandas向量化操作避免循环,性能提升明显:
import pandas as pd df1 = pd.DataFrame(data = {'Id': [12345678, 23456789, 34567890, 45678901, 56789012], 'score': [0.0123, 0.0145, 0.0345, 0.5660, 1.0000], 'target': [0, 0, 0, 1, 1]}) # 标记需要插入新行的位置 mask = df1['score'].diff(-1).abs() >= 0.01 # 批量构造需要插入的行 insert_df = df1[mask].copy() insert_df['score'] = (df1['score'] + df1['score'].shift(-1))[mask] / 2 # 新增排序字段保证合并后顺序正确 df1['sort_idx'] = df1.index * 2 insert_df['sort_idx'] = insert_df.index * 2 + 1 # 合并后排序,删除辅助字段 new_df = pd.concat([df1, insert_df], ignore_index=True)\ .sort_values('sort_idx')\ .reset_index(drop=True)\ .drop('sort_idx', axis=1) print(new_df)
内容的提问来源于stack exchange,提问作者mrcw
相关产品推荐
相关产品推荐

