Skip to content

Index

supplychain ¤

Supply Chain Events

Detectors for supply chain-related events and anomalies over shaped timeseries.

Classes: - InventoryMonitoringEvents: Low stock detection, consumption rate, reorder breach, stockout prediction. - LeadTimeAnalysisEvents: Lead time calculation, statistics, and anomaly detection. - DemandPatternEvents: Demand aggregation, spike detection, and seasonality analysis.

DemandPatternEvents ¤

DemandPatternEvents(
    dataframe: DataFrame,
    demand_uuid: str,
    *,
    event_uuid: str = "sc:demand",
    value_column: str = "value_double",
    time_column: str = "systime"
)

Bases: Base

Analyze demand patterns from a timeseries demand signal.

Each demand event is a numeric value representing demand quantity at a point in time.

Example usage

analyzer = DemandPatternEvents(df, demand_uuid='order_demand') daily = analyzer.demand_by_period(window='1D') spikes = analyzer.detect_demand_spikes(threshold_factor=2.0) seasonal = analyzer.seasonality_summary(window='1D')

Initialize demand pattern analyzer.

Parameters:

Name Type Description Default
dataframe DataFrame

Input DataFrame with timeseries data.

required
demand_uuid str

UUID of the demand signal.

required
event_uuid str

UUID assigned to generated events.

'sc:demand'
value_column str

Column containing numeric demand values.

'value_double'
time_column str

Name of timestamp column.

'systime'

demand_by_period ¤

demand_by_period(window: str = '1D') -> pd.DataFrame

Aggregate demand per time period.

Parameters:

Name Type Description Default
window str

Pandas offset alias for grouping (e.g. '1D', '1h').

'1D'

Returns:

Type Description
DataFrame

DataFrame with columns: start, end, duration_seconds, uuid,

DataFrame

source_uuid, is_delta, total_demand, avg_demand, peak_demand.

detect_demand_spikes ¤

detect_demand_spikes(
    threshold_factor: float = 2.0, window: str = "1D"
) -> pd.DataFrame

Flag periods where demand exceeds mean + threshold_factor * std.

Parameters:

Name Type Description Default
threshold_factor float

Number of standard deviations above the mean to flag as a spike.

2.0
window str

Pandas offset alias for aggregation period.

'1D'

Returns:

Type Description
DataFrame

DataFrame with columns: start, end, duration_seconds, uuid,

DataFrame

source_uuid, is_delta, demand, baseline_mean, spike_magnitude.

DataFrame

end is start plus window.

seasonality_summary ¤

seasonality_summary(window: str = '1D') -> pd.DataFrame

Compute demand patterns by day-of-week (for daily) or hour-of-day (for hourly).

When window='1D', groups by day of week (Monday=0 .. Sunday=6). When window is sub-daily (e.g. '1h'), groups by hour of day (0..23).

Parameters:

Name Type Description Default
window str

Pandas offset alias. '1D' for day-of-week analysis, any sub-daily frequency for hour-of-day analysis.

'1D'

Returns:

Type Description
DataFrame

DataFrame with columns: period_label, avg_demand, std_demand,

DataFrame

min_demand, max_demand.

InventoryMonitoringEvents ¤

InventoryMonitoringEvents(
    dataframe: DataFrame,
    level_uuid: str,
    *,
    event_uuid: str = "sc:inventory",
    value_column: str = "value_double",
    time_column: str = "systime"
)

Bases: Base

Monitor inventory levels from a timeseries signal and detect supply chain events.

Each inventory level is tracked via a UUID signal whose numeric value represents the current stock quantity.

Example usage

tracker = InventoryMonitoringEvents(df, level_uuid='warehouse_a_level') low = tracker.detect_low_stock(min_level=100, hold='5min') rate = tracker.consumption_rate(window='1h') breach = tracker.reorder_point_breach(reorder_level=200, safety_stock=50) prediction = tracker.stockout_prediction(consumption_rate_window='4h')

Initialize inventory monitoring.

Parameters:

Name Type Description Default
dataframe DataFrame

Input DataFrame with timeseries data.

required
level_uuid str

UUID of the inventory level signal.

required
event_uuid str

UUID assigned to generated events.

'sc:inventory'
value_column str

Column containing numeric inventory levels.

'value_double'
time_column str

Name of timestamp column.

'systime'

detect_low_stock ¤

detect_low_stock(
    min_level: float,
    hold: str = "0s",
    *,
    interval_end: str = "next_change"
) -> pd.DataFrame

Flag intervals where inventory stays below min_level for at least hold.

Parameters:

Name Type Description Default
min_level float

Threshold below which stock is considered low.

required
hold str

Minimum duration the level must stay below threshold (e.g. '0s', '5min', '1h').

'0s'
interval_end str

"next_change" (default) ends an interval at the next sample (the transition), so the interval spans the time the condition held and change-encoded signals -- one row per change -- keep their duration. "last_sample" ends it at its last flagged sample. See :func:ts_shape.utils.intervals.interval_end_times.

'next_change'

Returns:

Type Description
DataFrame

DataFrame with columns: start, end, uuid, source_uuid, is_delta,

DataFrame

min_value, avg_value, duration_seconds.

consumption_rate ¤

consumption_rate(
    window: str = "1h", *, handle_refills: bool = True
) -> pd.DataFrame

Calculate rolling consumption rate from inventory level decreases.

The rate is expressed as units consumed per hour within each window.

Parameters:

Name Type Description Default
window str

Time-based window for grouping (e.g. '1h', '30min').

'1h'
handle_refills bool

When True (default) only level decreases are summed (a refill is treated like a counter reset), booked in the window of the reading that reports them. When False consumption is first - last level of the window, so a refill inside the window cancels out the consumption (100 -> 40 -> 100 -> 40 reads as 0).

True

Returns:

Type Description
DataFrame

DataFrame with columns: start, end, duration_seconds, uuid,

DataFrame

source_uuid, is_delta, consumption_rate, level_start, level_end.

DataFrame

end is start plus window.

reorder_point_breach ¤

reorder_point_breach(
    reorder_level: float, safety_stock: float = 0.0
) -> pd.DataFrame

Detect when inventory falls below reorder point or safety stock level.

Parameters:

Name Type Description Default
reorder_level float

The reorder point threshold.

required
safety_stock float

Safety stock threshold (must be <= reorder_level).

0.0

Returns:

Type Description
DataFrame

DataFrame with columns: systime, uuid, source_uuid, is_delta,

DataFrame

current_level,

DataFrame

breach_type ('reorder' or 'safety_stock'), deficit.

stockout_prediction ¤

stockout_prediction(
    consumption_rate_window: str = "4h",
    *,
    handle_refills: bool = True
) -> pd.DataFrame

Estimate time until stockout based on recent consumption rate.

For each data point, uses the consumption rate calculated over the preceding consumption_rate_window to project when inventory will reach zero.

Parameters:

Name Type Description Default
consumption_rate_window str

Lookback window for calculating consumption rate (e.g. '4h').

'4h'
handle_refills bool

When True (default) the consumption in the lookback is the sum of the level decreases between consecutive samples (the same refill-aware rule as :meth:consumption_rate), so a refill inside the window does not cancel the consumption around it. When False it is the level at the window's first sample minus the level at its last (a refill then hides consumption, often giving 0).

True

Returns:

Name Type Description
DataFrame

DataFrame with columns: systime, uuid, source_uuid, is_delta,

DataFrame

current_level,

DataFrame

consumption_rate (units per hour), estimated_stockout_time_hours.

DataFrame

estimated_stockout_time_hours is NaN where the level is not

falling no consumption in the window

no stockout is

DataFrame

projected.

LeadTimeAnalysisEvents ¤

LeadTimeAnalysisEvents(
    dataframe: DataFrame,
    *,
    event_uuid: str = "sc:lead_time",
    time_column: str = "systime"
)

Bases: Base

Analyze lead times between order placement and delivery in timeseries data.

Order and delivery events are identified by separate UUIDs. When the delivery rows carry the order identifier, each order is matched to the first delivery of the same identifier at or after it; otherwise each order, in time order, is paired with the first not yet used delivery at or after it.

Example usage

analyzer = LeadTimeAnalysisEvents(df) lead_times = analyzer.lead_times('order_signal', 'delivery_signal') stats = analyzer.lead_time_statistics('order_signal', 'delivery_signal') anomalies = analyzer.detect_lead_time_anomalies('order_signal', 'delivery_signal')

Initialize lead time analyzer.

Parameters:

Name Type Description Default
dataframe DataFrame

Input DataFrame with timeseries data.

required
event_uuid str

UUID assigned to generated events.

'sc:lead_time'
time_column str

Name of timestamp column.

'systime'

lead_times ¤

lead_times(
    order_uuid: str,
    delivery_uuid: str,
    value_column: str = "value_string",
) -> pd.DataFrame

Match order events to delivery events.

The value_column is used as an order identifier (e.g. PO number). When deliveries carry identifiers that occur among the orders, each order is matched to the first delivery with the same identifier at or after the order time (unmatched orders are left out). Otherwise each order, in time order, is paired with the first delivery at or after it that is not paired yet; orders and deliveries left without a partner are dropped with a :class:~ts_shape.errors.DataQualityWarning. A lead time is never negative.

Parameters:

Name Type Description Default
order_uuid str

UUID of the order placement signal.

required
delivery_uuid str

UUID of the delivery received signal.

required
value_column str

Column containing order identifiers.

'value_string'

Returns:

Type Description
DataFrame

DataFrame with columns: start, end, duration_seconds, order_time,

DataFrame

delivery_time, uuid, source_uuid, is_delta, lead_time_seconds,

DataFrame

lead_time_hours, order_id. start/end are the order and

DataFrame

delivery times; source_uuid is "<order_uuid>,<delivery_uuid>".

lead_time_statistics ¤

lead_time_statistics(
    order_uuid: str,
    delivery_uuid: str,
    value_column: str = "value_string",
) -> pd.DataFrame

Compute summary statistics of lead times.

Parameters:

Name Type Description Default
order_uuid str

UUID of the order placement signal.

required
delivery_uuid str

UUID of the delivery received signal.

required
value_column str

Column containing order identifiers.

'value_string'

Returns:

Type Description
DataFrame

Single-row DataFrame with columns: mean_hours, std_hours,

DataFrame

min_hours, max_hours, p95_hours, count.

detect_lead_time_anomalies ¤

detect_lead_time_anomalies(
    order_uuid: str,
    delivery_uuid: str,
    threshold_factor: float = 2.0,
    value_column: str = "value_string",
) -> pd.DataFrame

Flag lead times exceeding mean + threshold_factor * std.

Parameters:

Name Type Description Default
order_uuid str

UUID of the order placement signal.

required
delivery_uuid str

UUID of the delivery received signal.

required
threshold_factor float

Number of standard deviations above mean to flag as anomalous.

2.0
value_column str

Column containing order identifiers.

'value_string'

Returns:

Type Description
DataFrame

DataFrame with columns: systime, order_time, delivery_time, uuid,

DataFrame

source_uuid, is_delta, lead_time_hours, z_score. systime is

DataFrame

the delivery time (when the anomaly becomes known).