TimeSeries

TimeSeries(dates, values, interval='one_day')

A time series: an ordered collection of (date, value) ordinates on a time interval.

Mirrors the Numerics TimeSeries container. Every method returns a new object or a plain result rather than modifying this one, even where the library’s own method mutates in place.

dates may be datetime objects, numpy.datetime64, a pandas DatetimeIndex, ISO 8601 strings, or numeric seconds since 1970-01-01. Missing observations are nan in values and stay missing through every method that says so.

The interval is not merely a label: it is what :meth:shift walks with by="start", what :meth:peaks_over_threshold measures its independence criterion in, and what :meth:convert_interval converts from. Use "irregular" for an event series (annual maxima, peaks over threshold) whose spacing is not fixed.

Parameters

Name Type Description Default
dates array - like The ordinate dates. required
values array-like of float The ordinate values, one per date. required
interval str One of :func:ts_interval_names. Default "one_day". 'one_day'

Examples

>>> import numpy as np
>>> dates = np.arange("2000-01-01", "2000-01-11", dtype="datetime64[D]")
>>> ts = TimeSeries(dates, [3, 1, 4, 1, 5, 9, 2, 6, 5, 3])
>>> len(ts)
10
>>> ts.moving_average(period=3).values[:3].round(4)
array([2.6667, 2.    , 3.3333])

Attributes

Name Description
dates The ordinate dates as numpy.datetime64[s].
interval The time interval this series is on.
values The ordinate values.

Methods

Name Description
block_series Reduce the series to one value per time block – annual maxima and their relatives.
calendar_year The annual block series over calendar years.
clip Keep the ordinates inside [start, end]; both bounds must lie inside the span.
convert_interval Resample to another interval.
cumulative_sum Running total, treating a missing value as zero while accumulating.
difference Successive differences. The result keeps this series’ start date, not a shifted one.
duration The duration (percent-of-time exceedance) curve, as an n-by-2 array of percent and
fill_missing_dates Insert the ordinates a regular series is missing entirely, over [start, end].
from_frame Build a series from a pandas DataFrame (or any mapping of column name to array).
hypothesis_test The container’s seven-test battery over the observed values.
interpolate_missing Fill runs of missing values no longer than max_missing by linear interpolation.
monthly_frequency The number of ordinates falling in each calendar month, keyed by month abbreviation.
monthly_percentiles Percentiles within each calendar month: 12 rows, one column per probability.
monthly_statistics Per-calendar-month statistics: 12 rows of minimum, 5%, 25%, 50%, 75%, 95%, maximum,
moving_average Trailing moving average over the previous period ordinates.
moving_sum Trailing moving sum over the previous period ordinates.
peaks_over_threshold Extract independent peak events above threshold.
percentiles Percentiles of the observed values at the requested probabilities.
replace_missing Set every missing value to value.
resample_block_bootstrap A fixed-block bootstrap: contiguous blocks drawn uniformly with replacement.
resample_knn The conditional k-nearest-neighbour bootstrap of Lall and Sharma (1996).
seasonal_decompose Classical additive decomposition into trend, seasonal and residual components.
shift Move every date by whole days, months or years, or re-anchor the series.
sort Sort by "time" or "value", "ascending" or "descending".
standardize Subtract the mean and divide by the standard deviation of the observed values.
statistics The library’s fifteen-entry summary: length, missing count, extremes, moments,
to_frame Return the series as a pandas DataFrame of date and value.
transform Apply one of the library’s value transformations, returning a new series.
water_year The annual block series over a water year starting in start_month (October).

block_series

TimeSeries.block_series(
    window='water_year',
    block='maximum',
    smoothing='none',
    period=1,
    start_month=10,
    end_month=9,
)

Reduce the series to one value per time block – annual maxima and their relatives.

The result is an IRREGULAR series carrying the date of the observation the block function selected: the extreme observation’s own date for "minimum"/"maximum", the block’s last date for "sum"/"average".

A block containing a missing value is dropped by "sum" and "average" (the missing value propagates) but kept by "minimum" and "maximum" (the comparison is false against a missing value, so it is simply never selected).

smoothing applies BEFORE the block function, which is how an n-day average maximum is built: block_series(smoothing="moving_average", period=7) is the annual maximum 7-day mean.

calendar_year

TimeSeries.calendar_year(block='maximum', smoothing='none', period=1)

The annual block series over calendar years.

clip

TimeSeries.clip(start, end)

Keep the ordinates inside [start, end]; both bounds must lie inside the span.

convert_interval

TimeSeries.convert_interval(to, average=True)

Resample to another interval.

Interpolates to a finer interval and block-averages (or block-sums, with average=False) to a coarser one. Month, quarter, year and irregular intervals have no fixed number of hours, so converting to or from one raises.

cumulative_sum

TimeSeries.cumulative_sum()

Running total, treating a missing value as zero while accumulating.

Following the library, the result carries the DEFAULT "one_day" interval rather than this series’.

difference

TimeSeries.difference(lag=1, differences=1)

Successive differences. The result keeps this series’ start date, not a shifted one.

duration

TimeSeries.duration()

The duration (percent-of-time exceedance) curve, as an n-by-2 array of percent and value.

fill_missing_dates

TimeSeries.fill_missing_dates(start, end, value=float('nan'))

Insert the ordinates a regular series is missing entirely, over [start, end].

value defaults to nan, inserting the absent ordinates as MISSING – which is what a repair workflow wants: fill the dates first, then decide separately which gaps are short enough to interpolate. The core takes a finite fill value, so the nan case fills with a placeholder and then marks exactly the inserted dates missing (an inserted date is one the input did not have, so this is exact rather than a guess).

from_frame

TimeSeries.from_frame(frame, date='date', value='value', interval='one_day')

Build a series from a pandas DataFrame (or any mapping of column name to array).

hypothesis_test

TimeSeries.hypothesis_test(split_location=None)

The container’s seven-test battery over the observed values.

split_location is a 0-BASED position in the observed values (R’s ts_hypothesis_test takes the 1-based position, each language following its own convention); None, the default, splits the record in half.

Jarque-Bera for normality, Ljung-Box and Wald-Wolfowitz for independence, Mann-Whitney and Mann-Kendall for homogeneity, and a t-test and F-test comparing the two halves of the record. This is NOT the ten-test battery :func:~corehydropy.analysis_data_hypothesis_test runs on a flood-frequency data frame – they are different methods with different splits.

interpolate_missing

TimeSeries.interpolate_missing(max_missing=1, indexes=None)

Fill runs of missing values no longer than max_missing by linear interpolation.

A run reaching the END of the series is EXTRAPOLATED from the two preceding ordinates instead. Both paths work in date space, so an irregular spacing is honoured.

monthly_frequency

TimeSeries.monthly_frequency()

The number of ordinates falling in each calendar month, keyed by month abbreviation.

monthly_percentiles

TimeSeries.monthly_percentiles(probabilities=(0.05, 0.25, 0.5, 0.75, 0.95))

Percentiles within each calendar month: 12 rows, one column per probability.

monthly_statistics

TimeSeries.monthly_statistics()

Per-calendar-month statistics: 12 rows of minimum, 5%, 25%, 50%, 75%, 95%, maximum, mean.

A month with no observation keeps an all-zero row rather than a missing one, following the library. Missing values are filtered out – unlike :meth:monthly_percentiles, which does not filter them, so one missing value gives that month missing percentiles.

moving_average

TimeSeries.moving_average(period, min_valid_count=None)

Trailing moving average over the previous period ordinates.

The result is shorter than the input by period - 1, and each ordinate carries the date of its window’s LAST observation.

min_valid_count controls what a window holding missing values does. The default – None, meaning period – propagates strictly: any missing value in the window gives a missing result, matching pandas’s default min_periods. A smaller value averages the observed entries only.

moving_sum

TimeSeries.moving_sum(period, min_valid_count=None)

Trailing moving sum over the previous period ordinates.

See :meth:moving_average for min_valid_count; under a relaxed value the sum is over the observed entries only, with no rescaling.

peaks_over_threshold

TimeSeries.peaks_over_threshold(
    threshold,
    min_steps_between_events=1,
    smoothing='none',
    period=1,
)

Extract independent peak events above threshold.

Follows the clust method of the R POT package: the first exceedance opens a cluster, the first value back under the threshold closes it unless the minimum spacing has not yet elapsed, and the next exceedance opens the next cluster. Each cluster contributes its maximum.

percentiles

TimeSeries.percentiles(probabilities=(0.05, 0.25, 0.5, 0.75, 0.95))

Percentiles of the observed values at the requested probabilities.

replace_missing

TimeSeries.replace_missing(value, indexes=None)

Set every missing value to value.

resample_block_bootstrap

TimeSeries.resample_block_bootstrap(time_steps, block_size, seed=12345)

A fixed-block bootstrap: contiguous blocks drawn uniformly with replacement.

Preserves the marginal distribution and the within-block dependence, at the cost of a discontinuity at each block boundary.

References

Kuensch, H.R. (1989). The jackknife and the bootstrap for general stationary observations. Annals of Statistics 17(3), 1217-1241.

resample_knn

TimeSeries.resample_knn(time_steps, k, seed=12345)

The conditional k-nearest-neighbour bootstrap of Lall and Sharma (1996).

At each step it finds the k historical observations closest to the current value, picks one at random, and advances to whatever historically came NEXT. That conditioning is what preserves the lag-1 structure – returning the neighbour’s own value instead would collapse the trajectory toward its starting point.

The draw happens inside the shared C++ core, so a seeded call gives bit-identical results in Python and R.

References

Lall, U. and Sharma, A. (1996). A nearest neighbor bootstrap for resampling hydrologic time series. Water Resources Research 32(3), 679-693.

seasonal_decompose

TimeSeries.seasonal_decompose(period)

Classical additive decomposition into trend, seasonal and residual components.

The seasonal part is extracted by keeping only the harmonics of the seasonal frequency. The trend is a moving average over period ordinates, so it – and the residual with it – is undefined for the first period - 1 ordinates, reported as nan. Where all three are defined they add back to the original value exactly.

Returns a dict of date, trend, seasonal and residual arrays, one entry per input ordinate.

shift

TimeSeries.shift(by='day', amount=0, start=None)

Move every date by whole days, months or years, or re-anchor the series.

With by="start" the series is re-anchored at start and the rest re-walked at its interval; on an "irregular" series only the first ordinate moves, since there is no interval to walk.

sort

TimeSeries.sort(by='time', order='ascending')

Sort by "time" or "value", "ascending" or "descending".

standardize

TimeSeries.standardize()

Subtract the mean and divide by the standard deviation of the observed values.

statistics

TimeSeries.statistics()

The library’s fifteen-entry summary: length, missing count, extremes, moments, percentiles.

to_frame

TimeSeries.to_frame()

Return the series as a pandas DataFrame of date and value.

Falls back to a dict of arrays when pandas is not installed – pandas is optional, not a dependency.

transform

TimeSeries.transform(fun, constant=0.0, power=1.0, base=10.0, indexes=None)

Apply one of the library’s value transformations, returning a new series.

fun is one of "add", "subtract", "multiply", "divide", "absolute_value", "exponentiate", "logarithm", "inverse".

Every transformation LEAVES A MISSING VALUE MISSING except "logarithm", which writes a missing value for any non-positive input. indexes restricts the transformation to the given 0-based ordinate positions; "logarithm" and "inverse" raise on an out-of-range index while the others skip it, because the library does.

water_year

TimeSeries.water_year(
    block='maximum',
    smoothing='none',
    period=1,
    start_month=10,
)

The annual block series over a water year starting in start_month (October).