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

如何基于时间序列连续性拆分Pandas DataFrame为无NaN子集

Pandas 时间序列连续子集拆分方案

针对300万行规模的数据集,以下方案全用Pandas原生向量化操作实现,运行效率足够满足需求,无需额外依赖。

核心思路

我们只需要对两类断裂点做标记,将连续的非断裂行归为同一分组即可完成拆分:

  • 断裂点1:任意指定列存在NaN值
  • 断裂点2:当前行与上一行的时间索引差不等于固定时间步长(步长可根据你的数据采样规则自定义,比如示例中的1小时)

实现代码

import pandas as pd

def split_continuous_subsets(df: pd.DataFrame, target_cols: list, freq: str = "H") -> list[pd.DataFrame]:
    # 复制原数据避免修改原表
    df = df.copy().sort_index()
    # 条件1:指定列全为非NaN的行标记为True,否则为False
    no_nan_mask = df[target_cols].notna().all(axis=1)
    # 条件2:时间连续的行标记为True,否则为False,先计算期望的连续时间差
    expected_delta = pd.Timedelta(freq)
    time_continuous_mask = df.index.to_series().diff() == expected_delta
    # 生成组ID:只要出现断裂点,组ID就+1
    group_id = (~(no_nan_mask & time_continuous_mask)).cumsum()
    # 过滤掉包含NaN的行,按组ID拆分
    subsets = [subset for _, subset in df[no_nan_mask].groupby(group_id)]
    return subsets

调用示例

用你给出的测试场景验证:

# 构造测试数据
idx = pd.date_range("2021-08-21 11:00:00", periods=7, freq="H", tz="UTC")
df = pd.DataFrame(
    {"x1": [1,2,3,4,5,6,7], "x2": [10,20,30,None,50,60,70]},
    index=idx
)
df.index.name = "predicted_at"

# 调用拆分函数,指定要校验的列x1、x2,时间步长为1小时
subsets = split_continuous_subsets(df, target_cols=["x1", "x2"], freq="H")

返回的subsets列表就包含两个子集:

  • 第一个子集对应11:00-13:00的3行无NaN数据
  • 第二个子集对应15:00-17:00的3行无NaN数据

自定义调整说明

  • 如果你的时间序列不是固定频率,可以把freq参数替换为你实际的采样间隔,比如freq="15T"代表15分钟采样
  • 如果不需要校验时间连续性,只需要按NaN断裂拆分,删除time_continuous_mask相关判断即可,仅保留no_nan_mask生成组ID

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 01:36:05