hypertools.save

hypertools.save(obj, fname, protocol=None)[source]

Save obj to fname, choosing the output format from the file extension.

Extension-aware export (QC 2026-07, F20-save-002/-010): files named with a recognized data extension are written in that REAL format, so external tools (pandas/numpy/R/Excel/MATLAB) can read them; every format also round-trips through hypertools.load().

extension

written as

.csv / .tsv / .txt

delimited text (via DataFrame.to_csv; comma, tab, and comma respectively). non-DataFrame input is converted with pd.DataFrame(np.asarray(obj)); a non-default index is included

.npy

numpy.save binary array

.npz

numpy.savez archive: a list/tuple saves one array per element, a dict one array per key, anything else a single array

.json

DataFrame.to_json

.parquet

DataFrame.to_parquet (column names are stringified, as parquet requires)

.mat

MATLAB file via scipy.io.savemat (arrays land in the variable 'data'; dicts map keys to variables)

.xlsx

Excel workbook via DataFrame.to_excel

anything else

a Python pickle (including .pkl/.pickle/ .p/.geo, unknown extensions, and paths with no extension)

Writes are atomic: the data is serialized to a temporary file next to the target and moved into place only on success, so a failed save never destroys an existing file at that path. File permissions are handled explicitly: overwriting an existing file preserves that file’s mode, and a brand-new file is created with the conventional 0o666 & ~umask permissions – the private 0600 mode of the intermediate temporary file never leaks onto the result.

Changed in version 1.0: The signature was narrowed from save(obj, fname, **kwargs) to save(obj, fname, protocol=None): keyword arguments other than protocol= – which older versions accepted and silently ignored – now raise TypeError. Update calls that passed leftover kwargs (e.g. compression=) rather than relying on them being dropped.

Parameters:
objobject

What to save: a numpy array, pandas DataFrame, list of arrays, fitted model/Pipeline, dict of results, matplotlib Figure, or (for pickle output) any other picklable Python object. Data formats (.csv, .npy, …) require array-/table-like input.

fnamestr or path-like

Target path. ~ and $ENV_VARS are expanded, matching hypertools.load(). The extension selects the format (table above).

protocolint, optional

Pickle protocol version (pickle output only; default: pickle’s default protocol). Passing it with a data-format extension raises ValueError.

Returns:
None
Raises:
hypertools.core.exceptions.HypertoolsIOError

If the object cannot be serialized in the requested format (e.g. an unpicklable object holding an open file handle, or a nested dict aimed at .csv), or if the target path is invalid (missing parent directory, existing directory, no write permission).

TypeError

If fname is not a string or path-like object.

Examples

>>> import numpy as np, pandas as pd, hypertools as hyp
>>> hyp.save(np.random.rand(10, 3), 'data.pkl')     # pickle
>>> hyp.save(pd.DataFrame({'a': [1, 2]}), 'data.csv')  # real CSV
>>> hyp.load('data.csv')['a'].tolist()
[1, 2]

Warning

Pickled files can execute arbitrary code when loaded – only share/load pickles with sources you trust. For figures and animations, prefer hyp.plot(..., save_path='fig.png').