time_series Module#
Temporal analysis of epidemiological data.
This module provides functions for analyzing temporal patterns in epidemiological data, including epidemic curves, incidence rates, and temporal trend analysis.
Classes#
- class episia.stats.time_series.TimeAggregation(value)[source]#
Bases:
EnumTime aggregation methods.
- DAILY = 'daily'#
- MONTHLY = 'monthly'#
- WEEKLY = 'weekly'#
- YEARLY = 'yearly'#
- class episia.stats.time_series.TrendMethod(value)[source]#
Bases:
EnumMethods for trend analysis.
- LINEAR = 'linear'#
- LOESS = 'loess'#
- MOVING_AVERAGE = 'moving_average'#
- SPLINE = 'spline'#
- class episia.stats.time_series.EpidemicCurve(dates, counts, aggregated, aggregation=None, metadata=None)[source]#
Bases:
objectContainer for epidemic curve data.
- Parameters:
- __init__(dates, counts, aggregated, aggregation=None, metadata=None)#
Functions#
- episia.stats.time_series.calculate_incidence(cases, population, time_period=1.0)[source]#
Calculate incidence rates.
- Parameters:
- Returns:
Incidence rates per time period
- Return type:
Example
>>> calculate_incidence([10, 20, 30], 1000) array([0.01, 0.02, 0.03]) # per time unit
- episia.stats.time_series.calculate_attack_rate(cases, population)[source]#
Calculate attack rates (cumulative incidence).
- episia.stats.time_series.epidemic_curve(dates, counts, aggregation=TimeAggregation.DAILY, fill_missing=True)[source]#
Create epidemic curve from date-case data.
- Parameters:
dates (ndarray) – Array of dates
counts (ndarray) – Array of case counts
aggregation (TimeAggregation) – Time aggregation level
fill_missing (bool) – Fill missing dates with zeros
- Returns:
EpidemicCurve object
- Return type:
- episia.stats.time_series.moving_average(data, window=7, center=True)[source]#
Calculate moving average for smoothing time series.
- episia.stats.time_series.loess_smoothing(x, y, frac=0.3, iterations=1)[source]#
LOESS (Local Regression) smoothing.
- episia.stats.time_series.detect_epidemic_threshold(counts, method='moving_average', window=7, multiplier=2.0)[source]#
Detect epidemic threshold using various methods.
- episia.stats.time_series.reproductive_number(incidence, serial_interval=5.0, method='cori')[source]#
Estimate time-varying reproductive number (R_t).
- episia.stats.time_series.seasonality_decomposition(time_series, period=365, model='additive')[source]#
Decompose time series into trend, seasonal, and residual components.
- episia.stats.time_series.exponential_growth_rate(cases, time_points=None)[source]#
Calculate exponential growth rate from case counts.
- episia.stats.time_series.nowcasting(reported_cases, delay_distribution, method='simple')[source]#
Perform nowcasting to estimate true incidence accounting for reporting delays.
- episia.stats.time_series.cumulative_curve(daily_cases)[source]#
Calculate cumulative epidemic curve.
Examples#
Creating an epidemic curve:
import pandas as pd
from episia.stats.time_series import epidemic_curve, TimeAggregation
dates = pd.date_range('2024-01-01', periods=100, freq='D')
cases = np.random.poisson(lam=5, size=100)
curve = epidemic_curve(dates, cases, aggregation=TimeAggregation.WEEKLY)
print(curve.summary())
# Convert to DataFrame for analysis
df = curve.to_dataframe()
Moving average smoothing:
from episia.stats.time_series import moving_average
smoothed = moving_average(cases, window=7)
# 7-day moving average
for i, (orig, smooth) in enumerate(zip(cases[:10], smoothed[:10])):
print(f"Day {i+1}: {orig} → {smooth:.1f}")
Detecting epidemic threshold:
from episia.stats.time_series import detect_epidemic_threshold
result = detect_epidemic_threshold(
cases,
method='moving_average',
window=7,
multiplier=2.0
)
print(f"Threshold: {result['threshold']:.1f}")
print(f"Epidemic days: {result['epidemic_days']}")
Time-varying reproductive number:
from episia.stats.time_series import reproductive_number
Rt = reproductive_number(cases, serial_interval=5.0, method='cori')
for day, rt in enumerate(Rt[:30]):
if rt > 0:
print(f"Day {day+1}: Rt={rt:.2f}")
Exponential growth rate:
from episia.stats.time_series import exponential_growth_rate
growth = exponential_growth_rate(cases[:30])
print(f"Growth rate: {growth['growth_rate']:.3f} per day")
print(f"Doubling time: {growth['doubling_time']:.1f} days")
print(f"R²: {growth['r_squared']:.3f}")
Seasonality decomposition:
from episia.stats.time_series import seasonality_decomposition
# Annual data with weekly cases
weekly_cases = np.random.poisson(lam=10, size=104) # 2 years
decomp = seasonality_decomposition(weekly_cases, period=52, model='additive')
# Access components
trend = decomp['trend']
seasonal = decomp['seasonal']
residual = decomp['residual']
Peak detection:
from episia.stats.time_series import detect_peaks
peaks = detect_peaks(cases, distance=7, prominence=10)
print(f"Found {peaks['n_peaks']} peaks at indices: {peaks['peak_indices']}")