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

基于Variant维度的多列自定义窗口大小移动平均实现问题

问题排查与解决:按Variant计算移动平均的函数错误

问题背景

现有一个包含Date、Measurement 1至Measurement 10、Variant字段的大型多维DataFrame,已通过window_s_prüfpunkte函数计算每个Variant近两个月的出现频次平均值,代码如下:

def window_s_prüfpunkte(df, config_col, date_col, data_cols):
    results = {}
    for config in df[config_col].unique():
        config_df = df[df[config_col] == config]
        date_series = pd.to_datetime(config_df[date_col])
        monthly_count = config_df.groupby([date_series.dt.year, 
        date_series.dt.month]).count().rename_axis(['year', 'month'])[data_cols].reset_index()
        quantity_average = round(monthly_count[data_cols].mean().mean())
        results[config] = {'monthly_count': monthly_count,
                           'quantity_average': quantity_average}
    return results

unique_configs = FSC3_Z_df_12M['Configuration Summary'].unique()
window_results = {}
for config in unique_configs:
   config_df = FSC3_Z_df_12M[FSC3_Z_df_12M['Configuration Summary'] == config]
   window_results[config] = window_s_prüfpunkte(config_df, 'Configuration Summary', 
   'Datum LP', COLS_Delta_Z)

尝试编写moving_average_by_config函数,以每个Variant的平均值为窗口大小计算各Measurement列的移动平均,但函数无法正常运行:

def moving_average_by_config(df, config_col, date_col, data_cols, window_results):
    results = []
    for config in df[config_col].unique():
        config_df = df[df[config_col] == config]
        config_window_size = window_results[config]
        for data_col in data_cols:
            config_df[f'{data_col}_MA'] = config_df[data_col].rolling(window=config_window_size).mean()
        results.append(config_df)
    return pd.concat(results)

错误分析

  1. 窗口大小取值错误:window_results是双层嵌套字典,每个config对应的是window_s_prüfpunkte返回的完整结果字典(包含monthly_count和quantity_average),但rolling需要整数类型的窗口大小,直接传整个字典会触发类型错误。
  2. 冗余的循环调用:外层循环遍历每个config并单独传入window_s_prüfpunkte,但该函数内部已经会遍历所有unique config,完全可以直接传入整个DataFrame,避免重复计算。
  3. 视图修改警告:直接修改切片得到的config_df(DataFrame视图)会触发SettingWithCopyWarning,可能导致修改不生效或意外行为。

修复后的代码

第一步:修复窗口结果的生成逻辑

去掉冗余的外层循环,直接调用一次函数即可:

# 直接传入整个DataFrame,无需单独遍历config
window_results = window_s_prüfpunkte(FSC3_Z_df_12M, 'Configuration Summary', 'Datum LP', COLS_Delta_Z)

第二步:修复移动平均函数

修正窗口大小的取值路径,同时创建DataFrame副本避免视图修改问题:

def moving_average_by_config(df, config_col, data_cols, window_results):
    results = []
    for config in df[config_col].unique():
        # 创建副本,避免视图修改警告
        config_df = df[df[config_col] == config].copy()
        # 取出对应的窗口大小数值
        config_window_size = window_results[config]['quantity_average']
        # 跳过窗口大小为0的情况(避免rolling报错)
        if config_window_size <= 0:
            for data_col in data_cols:
                config_df[f'{data_col}_MA'] = None
        else:
            for data_col in data_cols:
                config_df[f'{data_col}_MA'] = config_df[data_col].rolling(window=config_window_size).mean()
        results.append(config_df)
    return pd.concat(results)

额外说明

  • 新增了窗口大小为0的判断逻辑,避免因计算出的平均值为0导致rolling函数报错。
  • 原函数中的date_col参数在移动平均计算中未被使用,因此可以移除,简化函数参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 13:02:34