Expand low-frequency time series (yearly/quarterly/monthly/weekly/daily) to higher frequencies with publication-aware forward fill.
Project description
timeseries-expand
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_flagcolumn - 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/endmust lie within the input data range; otherwiseValueError.start > endraisesValueErrorat config construction.- Accepts ISO date strings,
pd.Timestamp, ordatetime.date. Naive values are assumed UTC. - Combine with
date_formatfor 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.Timestamp或datetime.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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d2ca7f2cb14ca152461ad05387293befa797585d04a3f8418dfcf452a4e15ba1
|
|
| MD5 |
90c12ad5db773baf55a9acea161cb3a0
|
|
| BLAKE2b-256 |
c7847d9e205d22b1d639a2d876672c0a1422342bb666f52a419db9a54b29bf42
|
Provenance
The following attestation bundles were made for timeseries_expand-0.2.0.tar.gz:
Publisher:
release.yml on Lance-Chen/timeseries-expand
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
timeseries_expand-0.2.0.tar.gz -
Subject digest:
d2ca7f2cb14ca152461ad05387293befa797585d04a3f8418dfcf452a4e15ba1 - Sigstore transparency entry: 1822562757
- Sigstore integration time:
-
Permalink:
Lance-Chen/timeseries-expand@2e5184cbc2dedbf35336abfc69d9b66019774e69 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/Lance-Chen
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@2e5184cbc2dedbf35336abfc69d9b66019774e69 -
Trigger Event:
push
-
Statement type:
File details
Details for the file timeseries_expand-0.2.0-py3-none-any.whl.
File metadata
- Download URL: timeseries_expand-0.2.0-py3-none-any.whl
- Upload date:
- Size: 11.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b5df957700987e2c93de74e8ff3642662028a5fcb371bca67a857bf49df452bc
|
|
| MD5 |
e87aaccc30386cbb9f1e15ec5421fe76
|
|
| BLAKE2b-256 |
811aa5a2499f210556b6a24f7e911557851c2235a75f6d67389d170d932fbd41
|
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
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
timeseries_expand-0.2.0-py3-none-any.whl -
Subject digest:
b5df957700987e2c93de74e8ff3642662028a5fcb371bca67a857bf49df452bc - Sigstore transparency entry: 1822562808
- Sigstore integration time:
-
Permalink:
Lance-Chen/timeseries-expand@2e5184cbc2dedbf35336abfc69d9b66019774e69 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/Lance-Chen
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@2e5184cbc2dedbf35336abfc69d9b66019774e69 -
Trigger Event:
push
-
Statement type: