Skip to main content

Expand low-frequency time series (yearly/quarterly/monthly/weekly/daily) to higher frequencies with publication-aware forward fill.

Project description

timeseries-expand

CI PyPI License: MIT Python 3.10+

English | 中文


English

timeseries-expand expands low-frequency time series into high-frequency series with publication-aware forward fill — every published value carries forward until the next publication, rather than being interpolated or back-filled.

Built for real-world data: weekly releases shifted by holidays, monthly indicators with occasional gaps, annual statistics that need daily granularity for downstream models.

Why?

Most off-the-shelf resamplers assume strict periodicity. Real publishing schedules aren't like that:

  • A weekly coal price index published on Monday — except when Monday is a public holiday, when it's pushed to Tuesday or Wednesday.
  • A monthly indicator with the occasional skipped release.
  • An annual figure that downstream code needs at hourly granularity.

timeseries-expand handles these cases explicitly and flags gaps so you can audit them later.

Supported frequency ladder

Any source frequency can be expanded to any higher (finer) target frequency. The expansion rule is uniform: every published value carries forward until the next publication (publication-aware forward fill, semantics [T, T_next)).

Source ↓ / Target → Yearly Quarterly Monthly Semi-Month Weekly Daily Hourly
Yearly
Quarterly
Monthly
Semi-Month
Weekly
Daily
Hourly

21 supported combinations. Adding new frequencies is a single edit to the Frequency enum.

Install

pip install timeseries-expand

With Polars backend (faster on large inputs):

pip install timeseries-expand[polars]

Quick start

import pandas as pd
from timeseries_expand import ExpandConfig, FrequencyExpander

# Weekly coal price index, published roughly every Monday
df = pd.DataFrame({
    "timestamp": pd.to_datetime([
        "2024-01-08", "2024-01-15", "2024-01-22",  # normal weeks
        "2024-01-29",                              # pushed by holiday
        "2024-02-12",                              # Spring Festival gap
    ]),
    "value":     [101.5, 102.3, 103.1, 102.8, 104.2],
})

cfg = ExpandConfig(source_freq="W-MON", target_freq="h")
result = FrequencyExpander().expand(df, cfg)

print(result.head())
#                  timestamp  value  gap_flag
# 0  2024-01-08 00:00:00+00:00  101.5     False
# 1  2024-01-08 01:00:00+00:00  101.5     False
# ...

Examples

Run any of these from the project root:

# Weekly coal price -> hourly (uses examples/coal_price_weekly.csv)
ts-expand examples/coal_price_weekly.csv /tmp/coal_hourly.csv \
    --source-freq W-MON --target-freq h --timezone UTC

# Annual index -> daily
ts-expand examples/annual_index.csv /tmp/annual_daily.csv \
    --source-freq YE --target-freq D

# Monthly index -> weekly in Asia/Shanghai timezone
ts-expand examples/monthly_index.csv /tmp/monthly_weekly.csv \
    --source-freq ME --target-freq W-MON --timezone Asia/Shanghai

# Semi-monthly -> hourly
ts-expand examples/semi_monthly.csv /tmp/semi_monthly_hourly.csv \
    --source-freq SME --target-freq h

Features

  • Publication-aware forward fill — semantics [T, T_next) (carries forward to, but not including, the next release).
  • Gap detection — flags intervals exceeding 1.5× expected cadence; configurable via gap_threshold_multiplier.
  • Timezone-safe — internal UTC; DST-safe across all transitions.
  • Irregular schedule-tolerant — handles 6/8/9-day "weekly" gaps without crashing.
  • Property-tested — Hypothesis suite guarantees published values are preserved exactly.

Documentation

Full docs at https://Lance-Chen.github.io/timeseries-expand/.

Contributing

See CONTRIBUTING.md. Bug reports and feature requests welcome via GitHub Issues.

License

MIT — see LICENSE.


中文

timeseries-expand 用「按发布时点的前向填充」语义,将低频时间序列扩充到高频——每个发布值沿用至下一次发布,而非插值或反向填充。

为真实场景设计:被节假日推迟的周度发布、偶尔缺失的月度指标、需要小时级粒度的年度统计数据。

为什么需要它?

现成的时间序列库都假设严格的周期性,但真实的发布日程并非如此:

  • 煤价指数每周一发布——但如果周一是法定节假日,可能推迟到周二或周三。
  • 月度指标偶尔会缺失某一期。
  • 年度数据,下游模型需要日级甚至小时级粒度。

timeseries-expand 显式处理这些场景,并通过 gap_flag 标记异常,便于后续审查。

支持的频率阶梯

任意源频率可扩充到任意更高的目标频率。 扩充规则统一:每个发布值沿用至下一次发布(按发布时点的前向填充,语义 [T, T_next))。

源 ↓ / 目标 → 年度 季度 月度 半月 周度 日度 小时
年度
季度
月度
半月
周度
日度
小时

共支持 21 种组合。增加新频率只需修改 Frequency 枚举一行。

安装

pip install timeseries-expand

启用 Polars 后端(大数据量更快):

pip install timeseries-expand[polars]

快速上手

import pandas as pd
from timeseries_expand import ExpandConfig, FrequencyExpander

# 煤价指数,每周大致周一发布
df = pd.DataFrame({
    "timestamp": pd.to_datetime([
        "2024-01-08", "2024-01-15", "2024-01-22",  # 正常周
        "2024-01-29",                              # 节假日推迟
        "2024-02-12",                              # 春节假期空档
    ]),
    "val

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

timeseries_expand-0.1.1.tar.gz (5.6 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

timeseries_expand-0.1.1-py3-none-any.whl (10.4 kB view details)

Uploaded Python 3

File details

Details for the file timeseries_expand-0.1.1.tar.gz.

File metadata

  • Download URL: timeseries_expand-0.1.1.tar.gz
  • Upload date:
  • Size: 5.6 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for timeseries_expand-0.1.1.tar.gz
Algorithm Hash digest
SHA256 2bc394a0e7ca4abfce232a53b42b28317a776965297116d1c97a8e55b48552dd
MD5 f4855c53197aba273205e36dab0070d3
BLAKE2b-256 d5ef55e71ccd421a6612cbe9361292b09f9c42f6216d5a87844b9c9f8d697134

See more details on using hashes here.

Provenance

The following attestation bundles were made for timeseries_expand-0.1.1.tar.gz:

Publisher: release.yml on Lance-Chen/timeseries-expand

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file timeseries_expand-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for timeseries_expand-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 d45e982dcb72bdc9904262b03b5b3d3f4228dbcb17ef88ebcaaa385551531c10
MD5 218babec7252bdd0e99115a84d0e2c3f
BLAKE2b-256 9f5217e902f1d92cb732e3f82e04b1a7866f9bfa677ce0aabeeaef4c51fdf17b

See more details on using hashes here.

Provenance

The following attestation bundles were made for timeseries_expand-0.1.1-py3-none-any.whl:

Publisher: release.yml on Lance-Chen/timeseries-expand

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page