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

Pandas:按资产与时间维度分组用中位数替换异常值

解决方法

步骤1:从hour列提取日期

首先需要从包含日期和小时的hour列中分离出纯日期部分,用于后续分组:

import pandas as pd

# 将hour列转换为datetime格式,提取日期(注意格式匹配你的数据,这里是月/日/年 小时)
df['date'] = pd.to_datetime(df['hour'], format='%m/%d/%y %H').dt.date
# 如果你的日期格式是日/月/年,把format改成'%d/%m/%y %H'

步骤2:计算分组中位数并替换异常值

这里提供两种简洁的实现方式:

方式一:用merge批量替换

先计算每个资产+日期分组下非异常值的中位数,再合并回原表替换:

# 计算仅包含正常数据的分组中位数
median_df = df[df['outlier?'] == 'no'].groupby(['asset', 'date'])['value'].median().reset_index()
median_df.rename(columns={'value': 'median_value'}, inplace=True)

# 合并原表和中位数表
df = df.merge(median_df, on=['asset', 'date'], how='left')

# 替换异常值对应的value
df.loc[df['outlier?'] == 'yes', 'value'] = df.loc[df['outlier?'] == 'yes', 'median_value']

# 清理临时列
df.drop(['date', 'median_value'], axis=1, inplace=True)

方式二:用apply逐行处理(适合小数据集)

直接通过apply判断每行是否为异常值,若是则取对应分组的中位数:

# 定义替换逻辑
def replace_outlier(row):
    # 筛选同资产、同日期的正常数据
    normal_vals = df[(df['asset'] == row['asset']) & 
                     (df['date'] == row['date']) & 
                     (df['outlier?'] == 'no')]['value']
    # 返回中位数(如果无正常数据则返回原值,可根据需求调整)
    return normal_vals.median() if row['outlier?'] == 'yes' else row['value']

# 应用替换逻辑
df['value'] = df.apply(replace_outlier, axis=1)

# 清理临时列
df.drop('date', axis=1, inplace=True)

注意事项

  • 如果某个asset+date分组下全是异常值,中位数会返回NaN,此时可以根据需求替换为该资产的全局中位数、前一天的中位数等。
  • 确保pd.to_datetime的format参数与你的hour列格式完全匹配,否则会解析失败出现报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 18:54:40