pycatch22 computes the catch22 time-series features in Python. catch22 is a set of 22 features, selected from the more than 7000 in hctsa for their classification performance across 93 time-series classification problems (Lubba et al., 2019). They capture a time series's dynamics, such as its autocorrelation, distribution of values, extreme events, scaling and predictability, and are fast to compute. pycatch22 wraps the catch22 C code, and has no runtime dependencies.
📖 Full documentation: the Python guide, and what each feature measures.
pip install pycatch22Pre-built wheels are available for Python 3.9 and later on Linux, macOS and Windows.
Elsewhere (e.g., Python 3.8), pip builds pycatch22 from source, which needs a C compiler.
pycatch22 is also on conda-forge, thanks to @rpanai, although it can lag behind PyPI:
conda install -c conda-forge pycatch22Installing from source
The catch22 C code is a git submodule, so clone with submodules, then install (this needs a C compiler):
git clone --recurse-submodules https://github.com/DynamicsAndNeuralSystems/pycatch22.git
cd pycatch22
pip install .If you already cloned without --recurse-submodules, run git submodule update --init first.
import numpy as np
import pycatch22
x = np.sin(np.arange(500) * 2 * np.pi / 50) + 0.5 * np.random.default_rng(1).standard_normal(500)
results = pycatch22.catch22_all(x) # a dict of 'names' and 'values'
features = dict(zip(results['names'], results['values']))catch22_all takes any sequence of numbers (a list, tuple or numpy array), and returns the feature names and their values (as floats).
Select features by name rather than by position.
| Option | Effect |
|---|---|
catch24=True |
Also compute the mean and standard deviation (catch24; see below) |
short_names=True |
Also return 'short_names', e.g., acf_timescale for CO_FirstCrossing_acf_1e_pointOfCrossing |
mask_nans=False |
Return NaN for features that cannot be estimated, instead of masking them (see below) |
return_masked=True |
Also return 'masked', which says which values were masked |
For example:
results = pycatch22.catch22_all(x, catch24=True, short_names=True)
# short_names: ['mode_5', 'mode_10', 'outlier_timing_pos', 'outlier_timing_neg', 'acf_timescale', ...]
# values: [-0.1257, -0.8436, 0.032, -0.044, 7.896, ...] (rounded)Single features.
Compute one feature by its long or short name, or with its own function (both give exactly the value catch22_all gives, computing only that feature):
pycatch22.compute_feature(x, 'acf_first_min')
pycatch22.CO_FirstMin_ac(x)The feature table.
pycatch22.feature_table() lists each feature's name, short name, name before v1.0, and the hctsa code that reproduces it:
pycatch22.feature_table()[4]
# {'name': 'CO_FirstCrossing_acf_1e_pointOfCrossing', 'short_name': 'acf_timescale', 'legacy_name': 'CO_f1ecac',
# 'hctsa_call': "CO_FirstCrossing(x_z,'ac',1/exp(1),'both').pointOfCrossing"}Many time series.
pycatch22 releases Python's global interpreter lock while it computes, so threads (e.g., a concurrent.futures.ThreadPoolExecutor) compute the features of different time series in parallel.
For a worked example on a dataset, see @jmoo2880's demonstration notebook.
- Location and spread.
Each time series is z-scored before the 22 features are computed, so they measure its dynamics and are insensitive to its mean and variance.
If the mean and spread matter for your application, use
catch24=True, which adds the mean and standard deviation. - Features that cannot be estimated (e.g., for a constant series, or
dfaon a series shorter than 79 samples) are masked by default: set to a fixed value at the appropriate end of their range, so you always get 22 real numbers. Usemask_nans=Falseto getNaNinstead. A series containingNaNorInfgivesNaNfor every feature, with a warning. - Sampling. A time series is an ordered sequence of values without time stamps, assumed to be evenly sampled.
Feature values can change between versions, so report the version of pycatch22 you used so that your results can be reproduced.
- v1.0 (using catch22 v1.1.0): every feature now exactly reproduces its definition in hctsa v3.0.0, so values change for most features.
Several features are renamed (e.g.,
CO_f1ecacis nowCO_FirstCrossing_acf_1e_pointOfCrossing, andcentroid_freqis replaced by the median frequency,median_freq); the old function names still work, but are deprecated. Features that cannot be estimated are masked by default, all values are floats, and features are returned in catch22's order (which differs from earlier versions). See the catch22 v1.0.0 release notes for how each feature changed. - v0.6.0: four features were corrected to match their hctsa definitions (
PD_PeriodicityWang_th0_01,IN_AutoMutualInfoStats_40_gaussian_fmmi,SB_BinaryStats_mean_longstretch1andSB_BinaryStats_diff_longstretch0), and the short namestransition_matrixandSDbecametransition_varianceandstd. - v0.3:
CO_f1ecacchanged from an integer to a linearly interpolated real value.
See the releases for details.
If you use pycatch22, please cite the open-access paper:
C. H. Lubba, S. S. Sethi, P. Knaute, S. R. Schultz, B. D. Fulcher, N. S. Jones. catch22: CAnonical Time-series CHaracteristics. Data Mining and Knowledge Discovery 33, 1821–1852 (2019).
BibTeX
@article{lubba2019catch22,
title = {catch22: {CA}nonical {T}ime-series {CH}aracteristics},
author = {Lubba, Carl H. and Sethi, Sarab S. and Knaute, Philip and Schultz, Simon R. and Fulcher, Ben D. and Jones, Nick S.},
journal = {Data Mining and Knowledge Discovery},
volume = {33},
number = {6},
pages = {1821--1852},
year = {2019},
doi = {10.1007/s10618-019-00647-x}
}pycatch22 is licensed under the GNU GPL v3 (or later).
