Skip to main content

pyfsda

Call FSDA — the MATLAB Flexible Statistics and Data Analysis toolbox for robust statistics — from Python, using the MATLAB Engine as the computational backend. FSDA runs unmodified in MATLAB; pyfsda is a thin, routine-agnostic bridge that marshals data across the boundary.

Call any FSDA routine as a plain Python function — the MATLAB session starts on first use and is reused:

import pyfsda

d   = pyfsda.mahalFS(Y, MU, SIGMA)                # numeric array -> numpy ndarray
out = pyfsda.Score(y, X, la=la, intercept=True)  # struct        -> dict  (MATLAB-style options)
RAW, REW = pyfsda.mcd(Y, nargout=2)             # two outputs   -> tuple
pyfsda.stop()                                     # optional; also runs automatically at exit

pyfsda.<name> works for any FSDA function (from pyfsda import Score works too). Prefer managing the session yourself? Use the explicit engine:

from pyfsda import FsdaEngine

eng = FsdaEngine.start("mahalFS")
d   = eng.call("mahalFS", Y, MU, SIGMA)
eng.stop()

Requirements

pyfsda does not bundle MATLAB or FSDA — it drives your local install. You need:

  1. MATLAB with the FSDA Add-On installed and on the MATLAB path (verify which mahalFS inside MATLAB).
  2. matlabengine matching your MATLAB release. This is the one version constraint that matters: the matlabengine package on PyPI is release-locked, so install the one that pairs with your MATLAB — e.g. pip install "matlabengine==26.1.*" for R2026a. pyfsda lists matlabengine as a dependency but deliberately does not pin it, so it will not clobber a matching version you already have.
  3. Python 3.9–3.13 (whatever your MATLAB release's engine supports).

Install

pip install pyfsda
# then, if not already present, the matlabengine that matches YOUR MATLAB:
pip install "matlabengine==26.1.*"     # example: MATLAB R2026a

Verify your install

Run examples/smoke_test.py — it starts MATLAB and checks a few real FSDA routines against numpy oracles, printing RESULT: PASS when your MATLAB + FSDA + matlabengine setup is good:

python smoke_test.py                 # or:  python smoke_test.py /path/to/FSDA

For a worked, MATLAB-style example, see examples/score_example.py — the Box-Cox Score test on the wool dataset, calling Score(y, X, 'la', ..., 'intercept', true) the same way you would in MATLAB.

What crosses the boundary

call(name, *args, nargout=1, echo_output=False, options=None, **kwargs) marshals positional arguments in order and keyword arguments (and any options dict) as MATLAB name/value pairs. It runs through the MATLAB workspace so outputs the engine cannot return directly (tables, 2-D cells) are decoded MATLAB-side.

MATLAB value crosses as
numeric / logical array numpy.ndarray (natural shape, NaN/Inf preserved)
struct dict (recursed)
char / string scalar str
cell list
table / timetable dict {VariableNames, RowNames/RowTimes, data, height}
2-D cell nested list
nargout > 1 tuple of the above
graphics handle (matlab.graphics.*) not marshalled — request only data outputs

Conventions: a 1-D input crosses as a MATLAB row (pass an (n, 1) array for a column); outputs keep MATLAB's natural shape (no silent reshape); MATLAB indices stay 1-based.

Passing structures in — the boundary also marshals the other way, so a struct-consuming FSDA routine can be called with plain Python objects: a dict → MATLAB struct (recursively), a list[str] → cellstr, other lists → cell, and numbers/arrays/strings via the usual rules. This makes results round-trip: an FSDA result dict (e.g. from FSReda) can be handed straight back to a plot, and option structs like fground / databrush are just Python dicts — see examples/resfwdplot_brush_example.py.

Reserved keywords consumed by the bridge are only nargout, echo_output, options, and frames; every other keyword is forwarded to MATLAB (so FSDA's own msg option passes straight through). echo_output=True tees MATLAB's stdout/stderr to your terminal.

Optional pandas view (pip install pyfsda[pandas])

pandas is an optional dependency — import pyfsda works without it. When it is installed you get a DataFrame view over MATLAB tables, on the Python side only (the neutral dict stays the default and remains the cross-language contract):

  • Output: pass frames=True to receive table/timetable outputs as a pandas.DataFrame (index from RowNames/RowTimes) — e.g. out = pyfsda.univariatems(y, X, frames=True). The public helper pyfsda.to_dataframe(table_dict) converts a dict you already have.
  • Input: pass a pandas.DataFrame argument and it is marshalled to a MATLAB table (array2table, column names and any non-default index preserved). v1 covers numeric/logical columns; string/categorical/datetime columns raise a clear NotImplementedError.

Requesting frames=True (or passing a DataFrame) without pandas installed raises a clear pip install pyfsda[pandas] error.

For a full table in → table out round trip in one call, see examples/grpstatsFS_pandas_example.py: a numeric DataFrame goes into grpstatsFS and a labelled DataFrame of per-variable statistics (mean, median, std, MAD, skewness, medcouple) comes back via frames=True.

On the first pyfsda.<name>(...) call, pyfsda also prints (once, best-effort) the latest FSDA release available on GitHub, so you can check your install is current. FsdaEngine.start() additionally runs a MATLAB-side FSDA up-to-date check via FSDA's tuna utility (quiet unless an update is available). Both are gated by check_version — silence them with pyfsda.start(check_version=False) (or FsdaEngine.start(check_version=False)) before the first call.

Notes

  • MATLAB engine startup is slow — start one FsdaEngine and reuse it; always stop() explicitly.
  • Struct-arrays and datetime/duration scalars are out of scope for the generic converters.

License

EUPL-1.2 — consistent with FSDA's own licensing.

Metadata

Release files for pyfsda 0.5.0

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

Source distribution (sdist)

Source distribution for pyfsda 0.5.0
File Size Uploaded
pyfsda-0.5.0.tar.gz 39.5 kB Details

Built distribution (wheel)

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

Total release size: 62.9 kB

Release files / pyfsda-0.5.0.tar.gz

Download URL pyfsda-0.5.0.tar.gz
Size 39.5 kB
Tags Source
SHA-256 checksum
How to use checksums
54f76d2adab3670a8e8a9e008c4510fc4702151fe973221fe6451474eb75ed1a
BLAKE2b-256 checksum
How to use checksums
94ce3f4795b3d31bfd3a15c435ce16b2e8387572a63d77dd76e9022541edf8ca
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.5

Release files / pyfsda-0.5.0-py3-none-any.whl

Download URL pyfsda-0.5.0-py3-none-any.whl
Size 23.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7607d522d488f390c04108af542948f2f8517c500e9f4b3ecad1533b8434f6ca
BLAKE2b-256 checksum
How to use checksums
bfafcee331e598df7b92dcc0e265946d31f565d474041f5559348d25c1963f32
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.5

Release history Release notifications | RSS feed

This release

0.5.0 This release

2 release files

0.4.0

2 release files

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