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

如何用Polars处理含异常值的单调递增时序数据差值计算

解决Polars中单调递增数据的异常值平滑问题

针对你遇到的单调递增观测数据异常值处理需求,我们可以通过以下步骤实现目标结果:

核心思路

  1. 识别异常高点:标记所有当前值 > 下一个值的位置(这些是不符合单调递增规则的异常高点)。
  2. 修正异常值:
    • 若异常点是第一个元素,将其修正为下一个值 / 2(实现和下一个值的平均拆分)。
    • 若异常点不是第一个元素,将其修正为(前一个值 + 下一个值) / 2(保证前后累计值的平滑过渡)。
  3. 计算分钟增量:基于修正后的累计值,计算每分钟的增量(第一个增量为修正后的初始值,后续为当前值与前一个值的差值)。

完整实现代码

import polars as pl

# 示例数据
df = pl.DataFrame(dict(
  time= ['10:00', '10:01', '10:02', '10:03', '10:04', '10:05', '10:06'],
  value=[  1000 ,     10 ,     22 ,      22 ,     50 ,   1100 ,     60 ]
))

# 处理异常值并计算目标增量
result_df = df.with_columns(
    # 标记异常高点:当前值大于下一个值
    is_anomaly=pl.col('value').shift(-1) < pl.col('value'),
    # 获取下一个值和前一个值,用于修正异常
    next_value=pl.col('value').shift(-1),
    prev_value=pl.col('value').shift()
).with_columns(
    # 生成修正后的累计值
    corrected=pl.when(pl.col('is_anomaly'))
        # 第一个元素异常时,取下一个值的一半
        .then(pl.when(pl.col('prev_value').is_null())
              .then(pl.col('next_value') / 2)
              # 非第一个元素异常时,取前后值的平均值
              .otherwise((pl.col('prev_value') + pl.col('next_value')) / 2))
        # 非异常值保持原数据
        .otherwise(pl.col('value'))
).with_columns(
    # 计算每分钟增量:第一个值用修正后的初始值填充,后续用差值
    increment=pl.col('corrected').diff().fill_null(pl.col('corrected'))
)

# 查看结果
print(result_df.select('time', 'value', 'corrected', 'increment'))

输出结果

运行代码后,increment列即为你需要的目标结果:[5, 5, 12, 0, 28, 5, 5],对应输出如下:

shape: (7, 4)
┌────────┬───────┬──────────┬──────────┐
│ time   ┆ value ┆ corrected ┆ increment│
│ ---    ┆ ---   ┆ ---       ┆ ---      │
│ str    ┆ i64   ┆ f64       ┆ f64      │
╞════════╪═══════╪═══════════╪══════════╡
│ 10:00  ┆ 1000  ┆ 5.0       ┆ 5.0      │
│ 10:01  ┆ 10    ┆ 10.0      ┆ 5.0      │
│ 10:02  ┆ 22    ┆ 22.0      ┆ 12.0     │
│ 10:03  ┆ 22    ┆ 22.0      ┆ 0.0      │
│ 10:04  ┆ 50    ┆ 50.0      ┆ 28.0     │
│ 10:05  ┆ 1100  ┆ 55.0      ┆ 5.0      │
│ 10:06  ┆ 60    ┆ 60.0      ┆ 5.0      │
└────────┴───────┴───────────┴──────────┘

原代码问题分析

你之前的代码先将异常值设为0再尝试替换,但第一个异常点的shift()结果为null,导致修正后出现空值;同时diff()默认会让第一个增量为null,最终缺失前两个有效增量。通过直接修正异常点为合理的累计值,并填充第一个增量的空值,就能解决这些问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 20:45:14