hypertools.manip

hypertools.manip(data, model='ZScore', return_model=False, normalize=None, reduce=None, ndims=None, align=None, cluster=None, **kwargs)[source]

Apply a manipulation (or chain of manipulations) to data.

Manipulations run in native (per-dataset) space – no dataset is ever mixed row-wise with another: Smooth and Resample are applied independently to each dataset in a list. ZScore and Normalize transform each dataset separately too, but fit ONE shared set of statistics (mean/std, or baseline/peak) across every dataset in a list – like hypertools.normalize’s 'across' mode. There is currently no manip-level option for within-dataset statistics on a list; call manip on each dataset separately for that.

Parameters:
dataDataFrame/array or list/tuple of these

Dataset(s) to manipulate. A pandas Series is treated as a single-column dataset; a tuple of datasets is treated exactly like a list. None raises a TypeError.

modelstr, dict, class, instance, list, Pipeline, False, or None

Which manipulator(s) to apply (default: ‘ZScore’). False or None skips the manipulation entirely and returns the input unchanged (matching align/cluster/reduce’s skip contract).

  • A string is one of MANIPULATORS’ names (Normalize, ZScore, Smooth, Resample).

  • A dict may be the canonical {'model': ..., 'args': [...], 'kwargs': {...}} or the LEGACY {'model': ..., 'params': {...}} form (accepted for backward compatibility, but emits a DeprecationWarning).

  • A bare (uninstantiated) Manipulator subclass, or an already-constructed (unfitted) instance, is used directly.

  • A list chains its elements into a hypertools.Pipeline (GH #274/#153) and runs fit_transform end to end – e.g. model=[{'model': 'Smooth', 'kwargs': {'kernel_width': 25}}, {'model': 'Resample', 'kwargs': {'n_samples': 1000}}, 'ZScore']. Inside a list, each string is resolved first against MANIPULATORS, then the reduce, align, and cluster registries (in that order, GH #153) – so model=['Smooth', 'UMAP'] and model=['Smooth', 'HyperAlign'] both work, via hypertools.core.pipeline.Pipeline.

  • An ALREADY-FITTED Manipulator instance or Pipeline (returned from a previous manip(…, return_model=True) call) is applied to data via .transform (its learned parameters, e.g. ZScore’s fitted mean/std, are reused – not re-estimated).

return_modelbool

If True, also return the fitted (or reused) model: the fitted Manipulator when model was a single spec, or a fitted hypertools.Pipeline when model was a list (default: False).

normalize, reduce, align, clustermodel spec, False, or None

Cross-module stage kwargs (GH #138): when any of these is given, the other stages also run (via hypertools.core.pipeline.build_pipeline), in the canonical order manip -> normalize -> reduce -> align -> cluster (GH #153), with this function’s own model= slotted in at the manip stage (default: None for all four, i.e. only manip runs). False skips a stage, exactly like None.

ndimsint or None

Passed through to the reduce stage (as ndims=) when reduce= is also given.

**kwargs

Passed through to the manipulator’s constructor when model resolves to a class (ignored when model is a list, an already -instantiated instance, or a fitted model/Pipeline being reused).

Returns:
The manipulated data (and the fitted model/Pipeline if
return_model=True).

Notes

manip and hypertools.normalize follow different conventions for the same input: manip returns DataFrames (index/columns preserved) while normalize returns numpy arrays; manip propagates NaNs while normalize PPCA-imputes them at format time; manip z-scores with the sample std (ddof=1) while normalize uses the population std (ddof=0); and a 1-D array is treated as a single ROW by manip’s data funnel but as a single COLUMN by normalize.

Examples

>>> import numpy as np
>>> import hypertools as hyp
>>> x = np.arange(20, dtype=float).reshape(10, 2)
>>> z = hyp.manip(x, model='ZScore')
>>> np.allclose(z.mean(axis=0), 0.0)
True
>>> smoothed = hyp.manip(x, model='Smooth', kernel_width=5)
>>> smoothed.shape
(10, 2)
>>> chained = hyp.manip(x, model=[{'model': 'Resample',
...                                'kwargs': {'n_samples': 50}},
...                               'ZScore'])
>>> chained.shape
(50, 2)