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.

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

21 supported combinations.

Install

pip install timeseries-expand

Quick start

import pandas as pd
from timeseries_expand import expand

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

result = expand(df, source_freq="W-MON", target_freq="h")
print(result.head())

Features

  • Publication-aware forward fill - semantics [T, T_next) (carries forward until the next release)
  • Gap detection - flags intervals exceeding 1.5x expected cadence with gap_flag column
  • DST-safe - internal UTC, configurable display timezone
  • 21 frequency combinations - expand yearly/quarterly/monthly/weekly/daily data
  • 173 tests - pytest + Hypothesis property-based tests
  • 3 call patterns - functional API, class-based API, CLI

Custom output date format

Pass date_format to format output timestamps as strings using any pandas strftime pattern:

# Functional API
result = expand(df, "W-MON", "h", date_format="%Y-%m-%d %H:%M")
# Result: "2024-01-01 00:00"

result = expand(df, "ME", "D", date_format="%Y-%m")
# Result: "2024-01" (year-month only)

result = expand(df, "W-MON", "D", date_format="%Y W%W")
# Result: "2024 W01" (ISO week)

CLI:

ts-expand in.csv out.csv --source-freq W-MON --target-freq h \
    --date-format "%Y-%m-%d"

Common placeholders (pandas supports a subset of strftime):

code meaning example
%Y 4-digit year 2024
%m month (01-12) 01
%d day of month (01-31) 15
%H:%M hour:minute 09:30
%a weekday abbr Mon
%b month abbr Jan
%j day of year (001-366) 035
%W ISO week number (00-53) 05
%z UTC offset +0800

Omit date_format (default None) to keep output as Timestamp objects.

Custom output time range

Clip the output to a subset of the input range with start / end:

# Functional API
result = expand(df, "W-MON", "h", start="2024-03-01", end="2024-06-30")
# Output: 2024-03-01 to 2024-06-30 (clipped, no extrapolation)

result = expand(df, "W-MON", "h", start="2024-12-01")
# Only start: goes from 2024-12-01 to the input's last date

CLI:

ts-expand in.csv out.csv --source-freq W-MON --target-freq h \
    --start 2024-03-01 --end 2024-06-30

Rules:

  • start / end must lie within the input data range; otherwise ValueError.
  • start > end raises ValueError at config construction.
  • Accepts ISO date strings, pd.Timestamp, or datetime.date. Naive values are assumed UTC.
  • Combine with date_format for formatted output: expand(df, "W-MON", "h", start="...", date_format="%Y-%m-%d").

CLI

ts-expand input.csv output.csv --source-freq W-MON --target-freq h
ts-expand --version

Contributing

See CONTRIBUTING.md.

License

MIT - see LICENSE.


中文

timeseries-expand 用"按发布时点的前向填充"语义,将低频时间序列扩充到高频 - 每个发布值沿用至下一次发布。

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

支持的频率阶梯

任意源频率可扩充到任意更高的目标频率。共支持 21 种组合。

源 / 目标 年度 季度 月度 半月 周度 日度 小时
年度 - Y Y Y Y Y Y
季度 - - Y Y Y Y Y
月度 - - - Y Y Y Y
半月 - - - - Y Y Y
周度 - - - - - Y Y
日度 - - - - - - Y
小时 - - - - - - -

安装

pip install timeseries-expand

快速上手

import pandas as pd
from timeseries_expand import expand

df = pd.DataFrame({
    "timestamp": pd.to_datetime([
        "2024-01-08", "2024-01-15", "2024-01-22",
        "2024-01-29", "2024-02-12",
    ]),
    "value": [101.5, 102.3, 103.1, 102.8, 104.2],
})

result = expand(df, source_freq="W-MON", target_freq="h")
print(result.head())

核心特性

  • 按发布时点的前向填充 - 语义 [T, T_next),沿用至下一次发布
  • 间隙检测 - 默认 1.5 倍期望周期以上的间隔自动标记 gap_flag
  • DST 安全 - 内部 UTC,可配置显示时区
  • 21 种频率组合 - 年级/季度/月度/半月/周度/日度数据任意扩充
  • 173 个测试 - pytest + Hypothesis 属性测试
  • 3 种调用方式 - 函数式 API、类 API、CLI

自定义输出时间范围

使用 start / end 把输出裁剪到输入的子区间:

result = expand(df, "W-MON", "h", start="2024-03-01", end="2024-06-30")
# 输出:2024-03-01 到 2024-06-30(裁剪,不外推)

result = expand(df, "W-MON", "h", start="2024-12-01")
# 只给 start:从 2024-12-01 到输入的最后一个日期

CLI:

ts-expand in.csv out.csv --source-freq W-MON --target-freq h \
    --start 2024-03-01 --end 2024-06-30

规则

  • start / end 必须落在输入数据范围内,否则抛 ValueError
  • start > end 在配置构造时就抛 ValueError
  • 接受 ISO 日期字符串、pd.Timestampdatetime.date,naive 值假定为 UTC。
  • 可与 date_format 组合:expand(df, "W-MON", "h", start="...", date_format="%Y-%m-%d")

命令行

ts-expand input.csv output.csv --source-freq W-MON --target-freq h
ts-expand --version

文档

GitHub: https://github.com/Lance-Chen/timeseries-expand
PyPI: https://pypi.org/project/timeseries-expand/

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.2.0.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.2.0-py3-none-any.whl (11.6 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: timeseries_expand-0.2.0.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.2.0.tar.gz
Algorithm Hash digest
SHA256 d2ca7f2cb14ca152461ad05387293befa797585d04a3f8418dfcf452a4e15ba1
MD5 90c12ad5db773baf55a9acea161cb3a0
BLAKE2b-256 c7847d9e205d22b1d639a2d876672c0a1422342bb666f52a419db9a54b29bf42

See more details on using hashes here.

Provenance

The following attestation bundles were made for timeseries_expand-0.2.0.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.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for timeseries_expand-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b5df957700987e2c93de74e8ff3642662028a5fcb371bca67a857bf49df452bc
MD5 e87aaccc30386cbb9f1e15ec5421fe76
BLAKE2b-256 811aa5a2499f210556b6a24f7e911557851c2235a75f6d67389d170d932fbd41

See more details on using hashes here.

Provenance

The following attestation bundles were made for timeseries_expand-0.2.0-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