pylimma.normalize_cyclic_loess
- pylimma.normalize_cyclic_loess(x, weights=None, span=0.7, adaptive_span=False, iterations=3, method='fast')[source]
Cyclic LOESS normalisation of columns of a matrix.
Faithful port of R limma’s
normalizeCyclicLoess(limma/R/norm.R:535-580). All three R methods are implemented:"fast"(default): each column vs the row mean."pairs": pairwise loess over every column pair."affy": like"pairs"but accumulates all pair-wise adjustments then divides bynper iteration.
Probe-vector weights (length = number of rows in
x) are supported for all three methods and are threaded through toloess_fit()in the weighted path. The unweighted"fast"path keeps the legacy statsmodels lowess route (withit=3anddelta=0.01*range(x)) so existing pre-computed R-parity fixtures continue to pass bit-for-bit.Per-observation (matrix-shaped) weights are accepted by R’s signature but fail inside R’s own
loessFitcall with"y and weights have different lengths"- this is a latent bug in R limma. pylimma does not attempt to fix it; pass a probe-vector instead, or collapse your(n_genes, n_samples)weight matrix withrow_means = np.nanmean(w, axis=1)before calling.The
adaptive_spandefault ofFalsematches the installed R limma (3.66.0) used to generate the parity fixtures. The current upstream limma source (modified 25 Feb 2026) flips this default toTrue; pylimma will follow that change once the bundled limma version is upgraded.