Skip to main content

PyNumDiff

Python methods for numerical differentiation of noisy data, including multi-objective optimization routines for automated parameter selection.

Python for Numerical Differentiation of noisy time series data

Documentation Status Coverage Status PyPI

Introduction

PyNumDiff is a Python package that implements many methods for computing numerical derivatives and smooth estimates from noisy data, which can be a critical step in developing dynamic models or designing control. There are seven different families of methods in this repository:

  1. prefiltering followed by finite difference calculation
  2. iterated finite differencing
  3. polynomial fit methods
  4. basis function fit methods
  5. total variation regularization of a finite difference derivative
  6. generalized Kalman smoothing
  7. local approximation with linear model

All are ultimately smoothing with similar runtime and accuracy, but some have flexibility advantages over others, summarized in the table under Usage below. For further details and comparison, see section 7 of our Taxonomy Paper.

All methods have hyperparameters, described in the Sphinx documentation. We take a principled approach and propose a multi-objective optimization framework for choosing settings that minimize a loss function that balances faithfulness to data with smoothness of the derivative estimate. For more details, refer to this paper.

Installing

Dependencies are listed in pyproject.toml. They include the usual suspects like numpy and scipy, plus pywavelets for waveletdiff, tqdm for the optimizer, and cvxpy for robustdiff and tvrdiff.

The code is compatible with >=Python 3.11. Install from PyPI with pip install pynumdiff, from source with pip install git+https://github.com/florisvb/PyNumDiff, or from local download with pip install .. Call pip install pynumdiff[advanced] to automatically install optional dependencies from the advanced list, like CVXPY.

Usage

For more details, read our Sphinx documentation. The basic pattern of all differentiation methods is:

somethingdiff(x, dt, **kwargs)

where x is data, dt is a step size, and various keyword arguments control the behavior. Methods marked multidimensional take an axis argument selecting which dimension of a block to differentiate along, and those supporting variable step size rename the second parameter dt_or_t, which accepts either a constant step size or an array of sample locations. Handing a method data it doesn't support raises a ValueError explaining why.

Method Multidim Variable step Missing data Outliers Circular domain Needs CVXPY
kerneldiff ✓
butterdiff ✓
finitediff ✓
polydiff ✓ ✓ ✓
savgoldiff ✓
splinediff ✓ ✓ ✓
spectraldiff ✓
rbfdiff ✓ ✓
waveletdiff ✓
tvrdiff ✓ ✓ ✓
rtsdiff ✓ ✓ ✓ ✓
robustdiff ✓ ✓ ✓ ✓ ✓
lineardiff ✓ ✓

There is also presently a swathe of deprecated methods. Don't use them, but if you do you'll just get warnings telling you how to use whichever new-and-improved version. There are also a few minor methods kept for general interest (iterative_velocity and smooth_acceleration) but in practice dominated by or redundant with others from the table.

You can set the hyperparameters manually with a construction like:

from pynumdiff.submodule import method

x_hat, dxdt_hat = method(x, dt, param1=val1, param2=val2, ...)     

Or you can find hyperparameter settings by calling the multi-objective optimization algorithm from the optimize module:

from pynumdiff.optimize import optimize

# estimate cutoff_frequency by (a) counting the number of true peaks per second in the data or (b) look at power spectra and choose cutoff
tvgamma = np.exp(-1.6*np.log(cutoff_frequency) -0.71*np.log(dt) - 5.1) # see https://ieeexplore.ieee.org/abstract/document/9241009

params, val = optimize(somethingdiff, x, dt, tvgamma=tvgamma, # smoothness hyperparameter which defaults to None if dxdt_truth given
            dxdt_truth=None, # give ground truth data if available, in which case tvgamma goes unused
            search_space_updates={'param1':[vals], 'param2':[vals], ...})

print('Optimal parameters: ', params)
x_hat, dxdt_hat = somethingdiff(x, dt, **params)

tvgamma governs the smoothness targeted by the optimization procedure, with larger values yielding smoother derivatives. Its value is dependent upon sampling rate and frequency content of the underlying signal, and it is universal across methods, making it possible to compare results post optimization. A default search space is used to initialize and perform optimiation, defined at the top of optimize.py, with overwrites from search_space_updates. Be aware the optimization is a fairly heavy process.

Notebook examples

Much more extensive usage is demonstrated in Jupyter notebooks, described further in the README in the notebooks/ folder:

Repo Structure

  • .github/workflows contains .yaml that configures our GitHub Actions continuous integration (CI) runs.
  • docs/ contains make files and .rst files to govern the way sphinx builds documentation, either locally by navigating to this folder and calling make html or in the cloud by readthedocs.io.
  • notebooks/ contains Jupyter notebooks that demonstrate some usage of the library.
  • pynumdiff/ contains the source code. For a full list of modules and further navigation help, see the readme in this subfolder.
  • .coveragerc governs coverage runs, listing files and functions/lines that should be excluded, e.g. plotting code.
  • .editorconfig ensures tabs are displayed as 4 characters wide.
  • .gitignore ensures files generated by local pip installs, Jupyter notebook runs, caches from code runs, virtual environments, and more are not picked up by git and accidentally added to the repo.
  • .pylintrc configures pylint, a tool for autochecking code quality.
  • .readthedocs.yaml configures readthedocs and is necessary for documentation to get auto-rebuilt.
  • CITATION.cff is citation information for the Journal of Open-Source Software (JOSS) paper associated with this project.
  • LICENSE.txt allows free usage of this project.
  • README.md is the text you're reading, hello.
  • pyproject.toml governs how this package is set up and installed, including dependencies.

Citation

See CITATION.cff file, but here are some possible BibTeX entries for convenience.

PyNumDiff python package:

@article{PyNumDiff2022,
  doi = {10.21105/joss.04078},
  url = {https://doi.org/10.21105/joss.04078},
  year = {2022},
  publisher = {The Open Journal},
  volume = {7},
  number = {71},
  pages = {4078},
  author = {Floris van Breugel and Yuying Liu and Bingni W. Brunton and J. Nathan Kutz},
  title = {PyNumDiff: A Python package for numerical differentiation of noisy time-series data},
  journal = {Journal of Open Source Software}
}

Collection of numerical differentiation methods:

@misc{komarov2025taxonomynumericaldifferentiationmethods,
  title={A Taxonomy of Numerical Differentiation Methods},
  author={Pavel Komarov and Floris van Breugel and J. Nathan Kutz},
  year={2025},
  eprint={2512.09090},
  archivePrefix={arXiv},
  primaryClass={math.NA},
  url={https://arxiv.org/abs/2512.09090}
}

Optimization algorithm:

@article{ParamOptimizationDerivatives2020, 
doi={10.1109/ACCESS.2020.3034077}
author={F. {van Breugel} and J. {Nathan Kutz} and B. W. {Brunton}}, 
journal={IEEE Access}, 
title={Numerical differentiation of noisy data: A unifying multi-objective optimization framework}, 
year={2020}
}

Running the tests

We are using GitHub Actions for continuous integration testing.

Run tests locally by navigating to the repo in a terminal and calling

> pytest -s

Add the flag --plot to see plots of the methods against test functions. Add the flag --bounds to print $\log$ error bounds (useful when changing method behavior).

License

This project utilizes the MIT LICENSE. 100% open-source, feel free to utilize the code however you like.

Metadata

Release files for pynumdiff 0.2.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pynumdiff 0.2.4
File Size Uploaded
pynumdiff-0.2.4.tar.gz 19.0 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for pynumdiff 0.2.4
File Interpreter ABI Platform
pynumdiff-0.2.4-py3-none-any.whl Python 3 none any Details

Total release size: 19.1 MB

Release files / pynumdiff-0.2.4.tar.gz

Download URL pynumdiff-0.2.4.tar.gz
Size 19.0 MB
Tags Source
SHA-256 checksum
How to use checksums
200fb8548cac32b2dd455b7f38bb9655baddc7e306db70730884f40957e605a4
BLAKE2b-256 checksum
How to use checksums
dfe099ac48728a322a81942f7f7a4d29c4260c2d6427345b92f4d7731b0c75dc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release files / pynumdiff-0.2.4-py3-none-any.whl

Download URL pynumdiff-0.2.4-py3-none-any.whl
Size 78.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1f12037ffb0e36a38ec594ed9ad4ebb5437c22a426a1542fc38066c3764070ea
BLAKE2b-256 checksum
How to use checksums
bfe4ae52f5887801ce7c858c317199496895f036d279f02e381a3710a073f97a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release history Release notifications | RSS feed

0.3

2 release files

This release

0.2.4 This release

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2

2 release files

0.1.2

4 release files

0.1.1

4 release files

0.0.3

1 release file

0.0.2

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page