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'
|
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
|
|
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'
|
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'
|
interval_end
|
str
|
|
'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'
|
handle_refills
|
bool
|
When |
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
|
|
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'
|
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: |
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
|
|
|
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. |
DataFrame
|
delivery times; |
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. |
DataFrame
|
the delivery time (when the anomaly becomes known). |