Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Quickstart

Everything in this page is a real, runnable snippet. If you prefer an executable version with plots, jump to the guided tour notebook.

Install

uv add mypackage      # or: pip install mypackage

There are no runtime dependencies, so this pulls in nothing else.

Describe a series

summarize returns a frozen Summary — immutable, hashable, comparable.

import mypackage as mp

series = [2.0, 4.0, 4.0, 4.0, 5.0, 5.0, 7.0, 9.0]
summary = mp.summarize(series)

summary.count      # 8
summary.mean       # 5.0
summary.median     # 4.5
summary.std        # 2.1380899352993947
summary.spread     # 7.0

The variance uses the unbiased estimator by default. Pass ddof=0 for the population variance:

mp.summarize(series, ddof=0).variance   # 4.0

Stream it instead

When the data doesn’t fit in memory, RunningStats consumes it one value at a time in constant space:

stats = mp.RunningStats()
for value in series:
    stats.update(value)

stats.mean == mp.summarize(series).mean   # True

Smooth it

mp.moving_average(series, window=3)              # linear, symmetric
mp.exponential_moving_average(series, alpha=0.3) # linear, causal
mp.median_filter(series, window=3)               # non-linear, spike-proof

The filters differ in how they treat an isolated outlier:

spike = [1.0, 1.0, 99.0, 1.0, 1.0]

mp.moving_average(spike, 3)   # [1.0, 33.67, 33.67, 33.67, 1.0] — smeared
mp.median_filter(spike, 3)    # [1.0,   1.0,   1.0,   1.0, 1.0] — removed

Compose transforms

Pipeline fits each step on the output of the previous one, then applies them in order:

pipeline = mp.chain(
    mp.Clip(upper=50.0),      # drop implausible spikes first
    mp.Standardize(),         # then centre and scale
    mp.MovingAverage(3),      # finally smooth
)

clean = pipeline.fit_apply(series)

Pipelines compose with |, and the result is a new pipeline — neither operand is mutated:

extended = pipeline | mp.Clip(-3.0, 3.0)
len(pipeline), len(extended)   # (3, 4)

Handle failures

Every error derives from MypackageError:

try:
    mp.summarize([])
except mp.EmptySeriesError as err:
    print(err)      # 'series' must contain at least one value, got 0

…and from the closest standard-library exception, so existing except clauses keep working:

isinstance(mp.EmptySeriesError(), ValueError)   # True
isinstance(mp.NotFittedError(), RuntimeError)   # True

Next steps