A Julia package providing the core types for representing, composing, and evaluating time-series features. TimeseriesFeatures.jl functionality underpins packages such as Catch22.jl, and is built around three ideas: a Feature is a named function with a description and keywords; a FeatureSet is a collection of features that can be evaluated against one or many time series in a single call; and a FeatureArray is the labelled output, annotated with feature names along its first dimension (a subtype of AbstractDimArray).
The package also defines SuperFeatures for features that share a common preprocessing step (e.g. z-scoring) so that the shared computation is performed once per time series. All feature-set evaluations are dispatched through MoreMaps.jl, which provides configurable backends for sequential, threaded, distributed, and Dagger-based execution, as well as progress logging.
Below we provide a getting-started guide. For complete API details see the package documentation.
using Pkg
Pkg.add("TimeseriesFeatures")
using TimeseriesFeaturesA Feature is a function annotated with a name (a Symbol), a description, and a vector of keyword strings. The wrapped method should accept at minimum an AbstractVector of numbers:
𝑓 = Feature(sum, :sum, "Sum of time-series values", ["distribution"])
𝑓(1:10) # 55, equivalent to sum(1:10)
getname(𝑓) # :sum
getdescription(𝑓) # "Sum of time-series values"
getkeywords(𝑓) # ["distribution"]Features are callable like ordinary functions. When called on a Matrix the wrapped method is applied column-wise (each column is treated as a time series), regardless of any matrix method the underlying function might define.
A FeatureSet groups features so they can be evaluated together. It can be constructed from a vector of Features, or from parallel vectors of methods, names, descriptions, and keywords:
𝒇 = FeatureSet([sum, length],
[:sum, :length],
["∑x¹", "∑x⁰"],
[["distribution"], ["sampling"]])FeatureSets support indexing by integer, by symbol, or by a vector of symbols, returning either a single Feature or a sub-FeatureSet:
𝒇[:sum] # the :sum Feature
𝒇[[:sum, :length]] # a 2-feature FeatureSetThey also support array-style set operations: + concatenates, \ (or setdiff) removes, and ∩/∪ intersect/union by name. Two features are considered equal if their names match.
A single time series is provided as a Vector{<:Number}; multiple time series are stacked into the columns of a Matrix{<:Number} (or, more generally, into a higher-dimensional array where the first dimension indexes within a time series). For example:
𝐱 = randn(1000) # one time series
X = randn(1000, 10) # ten time series, one per columnCalling a feature set returns a FeatureArray:
𝐟 = 𝒇(𝐱) # a FeatureVector of length 2
F = 𝒇(X) # a 2×10 FeatureMatrixA FeatureArray behaves like an Array but is annotated with feature names along its first dimension. Names can be retrieved with getnames(F) and used directly for indexing:
F[:sum] # row of :sum values across the 10 time series
F[:sum, 3] # :sum value for the third time seriesWhen several features share an expensive preprocessing step — z-scoring, detrending, computing a power spectrum — it is wasteful to repeat that step for every feature. A SuperFeature pairs a feature with a super feature representing that preprocessing, and a SuperFeatureSet collects them. When evaluated, each unique super is computed once per time series and its result is reused across every feature that shares it:
zᶠ = TimeseriesFeatures.zᶠ # built-in z-score SuperFeature
𝑓₁ = SuperFeature(mean, zᶠ; merge = true) # mean of z-scored input
𝑓₂ = SuperFeature(std, zᶠ; merge = true) # std of z-scored input
𝒈 = SuperFeatureSet([𝑓₁, 𝑓₂])
𝒈(𝐱) # z-score is computed once, then reused for both featuresSuperFeatures can be nested (a super may itself be a SuperFeature); the display tree groups features by their root super for inspection.
A PairwiseFeature represents a measure defined between two time series, such as a correlation or covariance. The two built-ins are Pearson and Covariance:
Pearson(𝐱, randn(1000)) # scalar Pearson correlation
Pearson(X) # 10×10 matrix of pairwise Pearson correlationsBundle pairwise features into a PairwiseFeatureSet to evaluate several together. A SuperPairwiseFeature lets pairwise measures share preprocessing in the same way as univariate SuperFeatures.
Evaluating a feature set across many time series is dispatched through MoreMaps.jl. Pass a chart keyword to control the execution backend and progress reporting. The default is Chart(), i.e. plain sequential evaluation with no progress output; threading and progress logging are opt-in:
using MoreMaps
F = 𝒇(X) # default: sequential, no progress
F = 𝒇(X; chart = Chart(Threaded(), ProgressLogger())) # multithreaded with ProgressLogging.jl outputAvailable backends include Sequential(), Threaded(), Distributed(), and Daggermap(); available progress loggers include NoProgress(), LogLogger(n), ProgressLogger(), and TermLogger(). For example, to run distributed across worker processes with @info-style updates every 10 items:
using Distributed
addprocs(4)
@everywhere using TimeseriesFeatures
F = 𝒇(X; chart = Chart(Distributed(), LogLogger(10)))TimeseriesFeatures.jl loads optional functionality via package extensions when supporting packages are present in the active environment:
StatsBase— additional distributional features built onStatsBase.jl.DSP— spectral and filter-based features (loaded automatically whenDSP.jlis imported).Associations— information-theoretic measures fromAssociations.jl(loaded automatically whenAssociations.jlis imported).TimeseriesTools— interoperability withTimeseriesTools.jltime-series types.
- HCTSA.jl — Julia wrapper for the pyhctsa feature set.
- Catch22.jl — the 22 catch22 features wrapped as a
SuperFeatureSetover this package. - CatchaMouse16.jl — the catchaMouse16 features for fMRI time-series analysis.
- MoreMaps.jl — the mapping framework used to dispatch feature evaluation across backends.
- DimensionalData.jl — the labelled-array foundation that
FeatureArrayextends.