Skip to content

intervals

intervals ¤

Helpers for turning a state signal into intervals.

A recurring pattern across the production pack collapses consecutive equal-state rows into intervals and measures each interval's duration. The naive implementation closes an interval at the last sample that still carries the state, which never counts the time from that last sample to the actual transition. Two problems follow:

  • On densely, periodically sampled data every interval is undercounted by one sample period.
  • On change-encoded signals (is_delta=True -- one row per transition, the library's normal convention) each state is a single row, so start == end and the duration collapses to zero. Downtime, micro-stop and duty-cycle analyses then silently report nothing.

:func:state_intervals closes each interval at the next transition by default (interval_end="next_change"), which is correct for both dense and change-encoded data. interval_end="last_sample" closes it at the last sample that carries the state instead.

interval_end_times ¤

interval_end_times(
    times: Series, interval_end: str = "next_change"
) -> pd.Series

Per-row closing time for a segment that ends at that row.

For code that groups consecutive rows into segments itself: a segment whose last row has label i ends at interval_end_times(times)[i].

Parameters:

Name Type Description Default
times Series

Timestamps of one signal, ordered in time.

required
interval_end str

"next_change" (default) returns the next row's timestamp, i.e. the instant the following segment starts; the final row keeps its own timestamp. "last_sample" returns times unchanged, so a segment ends at its own last sample.

'next_change'

Returns:

Type Description
Series

A Series aligned with times.

state_intervals ¤

state_intervals(
    dataframe: DataFrame,
    *,
    time_column: str,
    state_column: str,
    interval_end: str = "next_change",
    data_end: Timestamp | None = None
) -> pd.DataFrame

Collapse consecutive equal-state rows into intervals.

Parameters:

Name Type Description Default
dataframe DataFrame

Rows for a single signal, ordered in time. Only time_column and state_column are used.

required
time_column str

Name of the timestamp column.

required
state_column str

Name of the (already resolved) state column. Any hashable state works -- booleans for run/idle, strings for an identifier at a station.

required
interval_end str

How to close each interval.

  • "next_change" (default): end is the timestamp of the next state change (the transition instant), so the interval spans the real time the state was held. The final, still-open interval is closed at data_end when provided, otherwise at its own last sample.
  • "last_sample": end is the last sample that carries the state. This undercounts by one sample on dense data and collapses to zero-length intervals on change-encoded signals.
'next_change'
data_end Timestamp | None

Optional bound for the final open interval when interval_end="next_change" (e.g. the end of the data window or "now"). Ignored in "last_sample" mode.

None

Returns:

Type Description
DataFrame

DataFrame with columns start, end, state,

DataFrame

duration_seconds (float), sample_count -- one row per interval,

DataFrame

in time order.

Raises:

Type Description
ValueError

If interval_end is not one of :data:INTERVAL_END_MODES.