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) – somodel=['Smooth', 'UMAP']andmodel=['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)