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

如何基于目标列连续序列用均值替换特征列值?代码问题排查

问题描述

拥有时序数据,需根据target列中的连续序列,计算对应feature1、feature2列的均值,并用该均值替换序列内的特征值。例如表格中target列的连续3个1序列,要计算该序列feature1和feature2的均值,再替换对应行的特征值,且对每个target序列执行此操作。

示例数据

IDtime(s)feature1feature2target
abc5002.5678991.128340
abc10002.4567891.234521
abc15002.3658991.543981
abc20002.5642891.323481
abc25002.2586991.793220
cba5005.3658993.543981
cba10005.5642893.323481
cba15005.2586994.793220

尝试的代码

def averaging(input_df: pd.DataFrame):
    output_df = input_df.copy()
    target_index = []
    
    for _, sub_df in input_df.groupby('ID'): 
        _index = sub_df.index
        _targets = sub_df['target'].tolist()

        before = 1 if _targets[0] == 1 else 0

        tmp = []
        if before:
            tmp.append(_index[0])

        for i, flag in enumerate(_targets):
            if flag == 1 and before == 0:
                tmp.append(_index[i]) 
            elif flag == 0 and before == 1:
                tmp.append(_index[i])
                target_index.append(tmp)
                tmp = []
            before = flag
            
        if tmp:
            tmp.append(_index[-1]+1)
            target_index.append(tmp)

    output_df['target_id'] = 0
    for i, (indexi, indexj) in enumerate(target_index):
        output_df.iloc[indexi:indexj]['target_id'] = i+1

    targetid2avg = output_df.loc[output_df['target_id']!=0].groupby('target_id')[['feature1', 'feature2']].mean()
    targetid2avg.columns = ['target_feature1', 'target_feature2']

    output_df = output_df.merge(targetid2avg, on='target_id', how='left')
    output_df.loc[output_df['target_id']!=0, ['feature1', 'feature2']] = output_df.loc[output_df['target_id']!=0, ['target_feature1', 'target_feature2']].values
    
    output_df = output_df.drop(columns=['target_feature1', 'target_feature2'], axis=1)
    
    return output_df

遇到的问题

为output_df的target_id列赋值时,该列始终为0,无法正确标记序列。


问题分析与解决

原代码问题根源

赋值target_id时,output_df.iloc[indexi:indexj]['target_id'] = i+1属于链式索引,会创建DataFrame的切片副本而非直接修改原DataFrame,导致赋值操作仅作用在副本上,原DataFrame的target_id列未被更新。

修正后的代码

将链式索引改为直接定位列的赋值方式,避免副本问题:

def averaging(input_df: pd.DataFrame):
    output_df = input_df.copy()
    target_index = []
    
    for _, sub_df in input_df.groupby('ID'): 
        _index = sub_df.index
        _targets = sub_df['target'].tolist()

        before = 1 if _targets[0] == 1 else 0

        tmp = []
        if before:
            tmp.append(_index[0])

        for i, flag in enumerate(_targets):
            if flag == 1 and before == 0:
                tmp.append(_index[i]) 
            elif flag == 0 and before == 1:
                tmp.append(_index[i])
                target_index.append(tmp)
                tmp = []
            before = flag
            
        if tmp:
            tmp.append(_index[-1]+1)
            target_index.append(tmp)

    output_df['target_id'] = 0
    target_col_idx = output_df.columns.get_loc('target_id')
    for i, (indexi, indexj) in enumerate(target_index):
        # 直接定位行和列,修改原DataFrame
        output_df.iloc[indexi:indexj, target_col_idx] = i+1

    targetid2avg = output_df.loc[output_df['target_id']!=0].groupby('target_id')[['feature1', 'feature2']].mean()
    targetid2avg.columns = ['target_feature1', 'target_feature2']

    output_df = output_df.merge(targetid2avg, on='target_id', how='left')
    output_df.loc[output_df['target_id']!=0, ['feature1', 'feature2']] = output_df.loc[output_df['target_id']!=0, ['target_feature1', 'target_feature2']].values
    
    output_df = output_df.drop(columns=['target_feature1', 'target_feature2'], axis=1)
    
    return output_df

更简洁的Pandas实现方案

利用Pandas分组功能,自动识别连续target=1序列,无需手动处理索引:

def averaging_simplified(input_df: pd.DataFrame):
    output_df = input_df.copy()
    
    # 按ID分组,生成连续target=1的序列标识
    output_df['target_id'] = output_df.groupby('ID').apply(
        lambda x: (x['target'] == 1).cumsum() * x['target']
    ).reset_index(level=0, drop=True)
    
    # 计算每个target_id对应的特征均值
    avg_df = output_df[output_df['target_id'] != 0].groupby('target_id')[['feature1', 'feature2']].mean()
    
    # 替换对应序列的特征值
    output_df = output_df.merge(avg_df, on='target_id', suffixes=('', '_avg'), how='left')
    output_df.loc[output_df['target_id'] != 0, ['feature1', 'feature2']] = output_df.loc[output_df['target_id'] != 0, ['feature1_avg', 'feature2_avg']].values
    
    # 清理临时列
    output_df = output_df.drop(columns=['feature1_avg', 'feature2_avg'])
    
    return output_df

代码说明

  • 生成target_id时,(x['target'] == 1).cumsum()对连续的1序列累加计数,再乘以x['target']让非1的行保持0,自动完成序列标记。
  • 后续均值计算和替换逻辑更简洁,避免手动处理索引的复杂操作,降低出错概率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 01:15:39