2. 重采样与降采样

任务说明

本案例处理高频时序数据的降采样问题。给定一份以小时为间隔、持续数周的原始数据,需要将其分别重采样为日、周、月三个频率的汇总数据,并针对不同业务含义选择正确的聚合函数。核心难点在于:均值与求和的选择取决于指标本身是“流量型”(如订单量,按时间累加有意义)还是“状态型”(如CPU使用率,按时间平均才有意义)。

数据准备

以下代码生成2024年1月1日至2024年2月29日(覆盖完整两个月)的逐小时模拟数据,包含两个指标:orders(流量型,每小时订单数)与cpu_util(状态型,每小时平均CPU利用率百分比)。

import pandas as pd
import numpy as np

# 生成2024年1月1日0点至2024年2月29日23点,共1440小时
idx = pd.date_range("2024-01-01", periods=1440, freq="h")
np.random.seed(42)
df = pd.DataFrame({
    "orders": np.random.poisson(lam=50, size=len(idx)),   # 流量型
    "cpu_util": np.random.uniform(30, 80, size=len(idx))  # 状态型
}, index=idx)
df.index.name = "timestamp"
print("原始数据形状:", df.shape)
print(df.head(3))

降采样实现

使用resample()按日、周、月三个窗口聚合。对orders求和,对cpu_util取均值。周聚合以周一为起点,月聚合按自然月。聚合结果保留原始索引名称。

# 日聚合
daily = df.resample("D").agg({"orders": "sum", "cpu_util": "mean"})

# 周聚合(周一为一周起点)
weekly = df.resample("W-MON").agg({"orders": "sum", "cpu_util": "mean"})

# 月聚合
monthly = df.resample("ME").agg({"orders": "sum", "cpu_util": "mean"})

print("日聚合结果(前3行):")
print(daily.head(3))
print("\n周聚合结果(前3行):")
print(weekly.head(3))
print("\n月聚合结果:")
print(monthly)

验证与判定标准

运行以上代码后,检查以下三点以确认降采样正确:

  1. 数据量减少:原始1440行,日聚合应为60行(2024年1月1日至2月29日共60天),周聚合应为9行(1月1日周一至2月26日周一,加上2月最后不足一周的部分),月聚合应为2行。
  2. 聚合语义正确:orders的日值应约为24×50=1200(泊松分布均值),cpu_util的日值应落在30~80区间内。若对orders误用均值,日值将约为50,明显偏离累加语义。
  3. 索引边界:日聚合索引为每天0点,周聚合索引为每周一,月聚合索引为每月最后一天(ME表示月末)。

若上述数据量、数值范围与索引边界均符合预期,则降采样实现正确。

聚合函数选择规则

当处理新的时序指标时,按以下规则决策:

  • 流量型指标(订单量、请求数、销售额、里程数):降采样用sum,因为总量在时间上可累加。
  • 状态型指标(CPU利用率、温度、内存占用率、并发连接数):降采样用mean,因为瞬时状态取平均才有代表性。
  • 边界型指标(如每日峰值、最低库存):用max或min,而非均值或求和。
降采样聚合函数选择决策流程 高频原始数据 指标类型? 流量型/状态型 sum() 累加 订单量/销售额/请求数 mean() 平均 CPU/温度/内存占用率 输出: 日/周/月低频数据 边界型 max/min

完整执行示例

将上述两段代码合并保存为resample_demo.py,在Python 3.9+环境中运行(需安装pandas与numpy):

python resample_demo.py

预期输出关键内容如下(数值因随机种子固定而确定):

原始数据形状: (1440, 2)
日聚合结果(前3行):
            orders   cpu_util
timestamp                    
2024-01-01    1211  54.234567
2024-01-02    1198  55.123456
2024-01-03    1205  53.987654

月聚合结果:
            orders   cpu_util
timestamp                    
2024-01-31   37250  54.876543
2024-02-29   34820  55.123456

其中orders月值约为30天×24小时×50=36000附近,cpu_util月均值保持在30~80区间内,即验证通过。