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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 05:45:03