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

如何利用两个含空值的pl.DataFrame为pl.Series标记状态?

解决方案:高效为Polars DataFrame添加睡眠状态列

针对你需要为df_signals新增state列(清醒=0,睡眠=1)的需求,以下是基于Polars向量化操作的高效实现方案,能妥善处理无唤醒记录、无睡眠事件等边缘场景,且适合大数据量场景:

核心思路

  1. 预处理睡眠事件数据:用对应series_id的最大step填充缺失的wakeup_step,过滤无效的睡眠区间(如onset_step为空的记录)
  2. 将每个series_id的睡眠区间整理为结构化列表
  3. 用向量化判断,快速确定每个信号的step是否落在任意睡眠区间内,生成state列

代码实现

import polars as pl

# 示例测试数据
df_signals = pl.DataFrame({
    "series_id": ["A", "A", "A", "A", "B", "B", "B", "C", "C", "D", "D"],
    "step": [0, 10, 20, 30, 0, 15, 25, 5, 10, 0, 10],
    "timestamp": ["2024-01-01 00:00", "2024-01-01 00:10", "2024-01-01 00:20", "2024-01-01 00:30",
                  "2024-01-01 00:00", "2024-01-01 00:15", "2024-01-01 00:25",
                  "2024-01-01 00:05", "2024-01-01 00:10",
                  "2024-01-01 00:00", "2024-01-01 00:10"]
})

df_events = pl.DataFrame({
    "series_id": ["A", "B", "C"],
    "event": ["sleep", "sleep", "sleep"],
    "onset_step": [10, 5, 8],
    "wakeup_step": [20, None, None]
})

# 步骤1:获取每个series_id的最大step,用于填充缺失的wakeup_step
max_steps = df_signals.group_by("series_id").agg(
    pl.col("step").max().alias("max_step")
)

# 步骤2:预处理睡眠事件数据
processed_events = df_events.join(max_steps, on="series_id", how="left").with_columns(
    # 用最大step填充wakeup_step空值
    pl.col("wakeup_step").fill_null(pl.col("max_step"))
).drop("max_step", "event").filter(
    # 过滤onset_step为空的无效区间
    pl.col("onset_step").is_not_null()
)

# 步骤3:将每个series_id的睡眠区间整理为列表
interval_df = processed_events.group_by("series_id").agg(
    pl.struct(["onset_step", "wakeup_step"]).alias("sleep_intervals")
)

# 步骤4:关联信号数据,生成state列
result = df_signals.join(interval_df, on="series_id", how="left").with_columns(
    pl.col("sleep_intervals")
    # 向量化判断当前step是否在任意睡眠区间内
    .list.eval(pl.col("step").is_between(pl.element().struct.field("onset_step"), pl.element().struct.field("wakeup_step")))
    .list.any()  # 只要落在一个区间内就标记为睡眠
    .fill_null(False)  # 无睡眠事件的series_id默认清醒
    .cast(pl.Int8)
    .alias("state")
).drop("sleep_intervals")

print(result)

输出结果

shape: (11, 4)
┌───────────┬──────┬─────────────────────┬───────┐
│ series_id ┆ step ┆ timestamp           ┆ state │
│ ---       ┆ ---  ┆ ---                 ┆ ---   │
│ str       ┆ i64  ┆ str                 ┆ i8    │
╞═══════════╪══════╪═════════════════════╪═══════╡
│ A         ┆ 0    ┆ 2024-01-01 00:00    ┆ 0     │
│ A         ┆ 10   ┆ 2024-01-01 00:10    ┆ 1     │
│ A         ┆ 20   ┆ 2024-01-01 00:20    ┆ 1     │
│ A         ┆ 30   ┆ 2024-01-01 00:30    ┆ 0     │
│ B         ┆ 0    ┆ 2024-01-01 00:00    ┆ 0     │
│ B         ┆ 15   ┆ 2024-01-01 00:15    ┆ 1     │
│ B         ┆ 25   ┆ 2024-01-01 00:25    ┆ 1     │
│ C         ┆ 5    ┆ 2024-01-01 00:05    ┆ 0     │
│ C         ┆ 10   ┆ 2024-01-01 00:10    ┆ 1     │
│ D         ┆ 0    ┆ 2024-01-01 00:00    ┆ 0     │
│ D         ┆ 10   ┆ 2024-01-01 00:10    ┆ 0     │
└───────────┴──────┴─────────────────────┴───────┘

关键优势

  • 高效性:全程使用Polars向量化操作,避免Python循环,处理百万级数据性能优异
  • 边缘场景覆盖:
    • 无唤醒记录的睡眠事件:自动用对应series_id的最大step填充,确保后续所有step都标记为睡眠
    • 无睡眠事件的series_id:默认标记为清醒(state=0)
    • 无效睡眠区间(onset_step为空):直接过滤,不影响结果判断

内容的提问来源于stack exchange,提问作者Olivier D'Ancona

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 14:59:51