我不知道我是否把事情复杂化了,但是:
我们想到的最初方法是对事件进行编号,以便它们与通道中的行索引对齐.
shape: (2, 2)
┌──────────────────────────────────┬───────┐
│ event_table ┆ index │
│ --- ┆ --- │
│ list[str] ┆ u32 │
╞══════════════════════════════════╪═══════╡
│ ["start_1", "stop_1", "start_2"] ┆ 0 │ # [1, 2, 3]
│ ["start_3", "stop_3"] ┆ 5 │ # [6, 7]
└──────────────────────────────────┴───────┘
我们可以得到每个通道0的行索引:
time_df.with_row_index("zero_index").filter(channel = 0).with_row_index()
shape: (2, 4)
┌───────┬────────────┬─────────┬──────┐
│ index ┆ zero_index ┆ channel ┆ time │
│ --- ┆ --- ┆ --- ┆ --- │
│ u32 ┆ u32 ┆ i64 ┆ f64 │
╞═══════╪════════════╪═════════╪══════╡
│ 0 ┆ 0 ┆ 0 ┆ 0.1 │
│ 1 ┆ 5 ┆ 0 ┆ 0.6 │
└───────┴────────────┴─────────┴──────┘
其中我们可以.join
个go 参加活动.
events_with_id = (
events_df
.with_row_index()
.join(
time_df.with_row_index("zero_index")
.filter(channel = 0)
.with_row_index()
.select("index", "zero_index"),
on = "index",
how = "left"
)
.select(
pl.col("event_table")
.list.slice(0, pl.col("zero_index").shift(-1) - pl.col("zero_index") - 1)
.fill_null(pl.col("event_table")),
index = "zero_index"
)
.explode("event_table")
.with_columns(
(pl.col("index") + pl.col("index").cum_count()).over("index")
)
)
在.explode()
人之后,我们拥有:
shape: (5, 2)
┌─────────────┬───────┐
│ event_table ┆ index │
│ --- ┆ --- │
│ str ┆ u32 │
╞═════════════╪═══════╡
│ start_1 ┆ 0 │
│ stop_1 ┆ 0 │
│ start_2 ┆ 0 │
│ start_3 ┆ 5 │
│ stop_3 ┆ 5 │
└─────────────┴───────┘
.cum_count()
的添加给我们:
shape: (5, 2)
┌─────────────┬───────┐
│ event_table ┆ index │
│ --- ┆ --- │
│ str ┆ u32 │
╞═════════════╪═══════╡
│ start_1 ┆ 1 │ # index of 1st channel 0 (plus 1)
│ stop_1 ┆ 2 │
│ start_2 ┆ 3 │
│ start_3 ┆ 6 │ # index of 2nd channel 0 (plus 1)
│ stop_3 ┆ 7 │
└─────────────┴───────┘
然后我们可以对其进行.join
,并最终过滤出通道0行.
(time_df
.with_row_index()
.join(
events_with_id,
on = "index",
how = "left"
)
.filter(pl.col("channel") != 0)
)
shape: (5, 4)
┌───────┬─────────┬──────┬─────────────┐
│ index ┆ channel ┆ time ┆ event_table │
│ --- ┆ --- ┆ --- ┆ --- │
│ u32 ┆ i64 ┆ f64 ┆ str │
╞═══════╪═════════╪══════╪═════════════╡
│ 1 ┆ 1 ┆ 0.2 ┆ start_1 │
│ 2 ┆ 2 ┆ 0.3 ┆ stop_1 │
│ 3 ┆ 1 ┆ 0.4 ┆ start_2 │
│ 4 ┆ 2 ┆ 0.5 ┆ null │
│ 6 ┆ 1 ┆ 0.7 ┆ start_3 │
└───────┴─────────┴──────┴─────────────┘
重叠部分
list.slice()
用于截断任何潜在的重叠:
shape: (2, 2)
┌─────────────────────────────────────────────────────────────────┬───────┐
│ event_table ┆ index │
│ --- ┆ --- │
│ list[str] ┆ u32 │
╞═════════════════════════════════════════════════════════════════╪═══════╡
│ ["start_1", "stop_1", "start_2", "stop_2", "start_3", "stop_3"] ┆ 0 │
│ ["start_4", "stop_4"] ┆ 5 │
└─────────────────────────────────────────────────────────────────┴───────┘
overlap.with_columns(
pl.col("event_table")
.list.slice(0, pl.col("index").shift(-1) - pl.col("index") - 1) # truncate
.fill_null(pl.col("event_table")) # refill last row
)
shape: (2, 2)
┌────────────────────────────────────────────┬───────┐
│ event_table ┆ index │
│ --- ┆ --- │
│ list[str] ┆ u32 │
╞════════════════════════════════════════════╪═══════╡
│ ["start_1", "stop_1", "start_2", "stop_2"] ┆ 0 │
│ ["start_4", "stop_4"] ┆ 5 │
└────────────────────────────────────────────┴───────┘