deepbox/stats
Descriptive & Correlation
Means, variances, quantiles, skewness and related summaries on tensors, plus Pearson, Spearman and Kendall correlation with p-values.
- Summaries
- Correlation
Overview
- These functions take tensors and reduce over every value or along
axis. The options form,std(t, { axis: 0, ddof: 1 }), is easier to read than positional flags.std,varianceandzscoredefault toddof = 0(population), whilecovandsemdefault toddof = 1. quantiletakesqin [0, 1] andpercentiletakes [0, 100]. Both interpolate linearly like NumPy and return afloat64tensor with one leading entry per requested quantile.pearsonr,spearmanr,kendalltauandpointbiserialrreturn[statistic, pvalue]. Theiralternativeoption is"two-sided"(default),"less"or"greater".kendalltaucomputes tau-b unless you passvariant: "c", and takesmethod: "auto" | "exact" | "asymptotic"for the p-value.corrcoefreads a 2-D tensor with observations in rows and variables in columns, the opposite of NumPy's default (rowvar=True).corrcoef(x, y)correlates two vectors. Constant input gives NaN, whilepearsonrthrows for it.ndarrayalso exportscorrcoefandcov. Use whichever module you already import from.
KurtosisOptions
interfaceOptions bag for kurtosis. Recommended so the two independent flags (fisher, bias) are named rather than positional booleans.
axis?: AxisLikeAxis or axes along which to reduce (undefined = all axes).
fisher?: booleanIf true, returns excess kurtosis (subtract 3, default: true).
bias?: booleanIf false, applies the bias correction (requires at least 4 samples, default: true).
MeanOptions
interfaceOptions bag for mean. Recommended over trailing positional flags, which are easy to confuse with the differently-typed flags on other reductions (e.g. skewness(t, axis, bias)).
axis?: AxisLikeAxis or axes along which to reduce (undefined = all axes).
keepdims?: booleanIf true, reduced axes are retained with size 1 (default: false).
SkewnessOptions
interfaceOptions bag for skewness. Recommended so the sample-correction flag is named rather than a bare trailing boolean.
axis?: AxisLikeAxis or axes along which to reduce (undefined = all axes).
bias?: booleanIf false, applies the unbiased Fisher-Pearson correction (default: true).
VarianceOptions
interfaceOptions bag for variance and std. Recommended over trailing positional flags: the keepdims/ddof pair is easy to transpose.
axis?: AxisLikeAxis or axes along which to reduce (undefined = all axes).
keepdims?: booleanIf true, reduced axes are retained with size 1 (default: false).
ddof?: numberDelta degrees of freedom (0 = population, 1 = sample, default: 0).
corrcoef
function corrcoef(x: Tensor, y?: Tensor): Tensor;Computes the Pearson correlation coefficient matrix.
For two variables, returns 2x2 correlation matrix. For a 2D tensor, treats each column as a variable and computes pairwise correlations.
Parameters
xTensor- Input tensor (1D or 2D)
yoptionalTensor- Optional second tensor (if provided, computes correlation between x and y)
Returns
TensorCorrelation matrix (symmetric with 1s on diagonal)
Throws
InvalidParameterErrorIf < 2 observations or size mismatchShapeErrorIf tensor is not 1D or 2D
const x = tensor([1, 2, 3, 4, 5]);const y = tensor([2, 4, 5, 4, 5]);corrcoef(x, y); // Returns [[1.0, 0.7746], [0.7746, 1.0]] const data = tensor([[1, 2], [3, 4], [5, 6]]);corrcoef(data); // Returns 2x2 correlation matrix for 2 variablescov
function cov(x: Tensor, y?: Tensor, ddof?: number): Tensor;Computes the covariance matrix.
Covariance measures how two variables change together. For two variables, returns 2x2 covariance matrix. For a 2D tensor, treats each column as a variable.
Parameters
xTensor- Input tensor (1D or 2D)
yoptionalTensor- Optional second tensor (if provided, computes covariance between x and y)
ddofoptionalnumber- Delta degrees of freedom (0 = population, 1 = sample, default: 1)
Returns
TensorCovariance matrix (symmetric)
Throws
InvalidParameterErrorIf tensor is empty, ddof is negative or not finite, ddof >= sample size, or size mismatchShapeErrorIf tensor is not 1D or 2D
const x = tensor([1, 2, 3, 4, 5]);const y = tensor([2, 4, 5, 4, 5]);cov(x, y); // Returns 2x2 covariance matrix const data = tensor([[1, 2], [3, 4], [5, 6]]);cov(data); // Returns 2x2 covariance matrix for 2 variableskendalltau
function kendalltau(x: Tensor, y: Tensor, options?: KendallTauOptions): [ number, number ];Computes Kendall's tau correlation coefficient.
Non-parametric measure of ordinal association based on concordant/discordant pairs. Less sensitive to outliers than Pearson, and with a simple probabilistic interpretation. - tau = 1: All pairs concordant (perfect agreement) - tau = 0: Equal concordant and discordant pairs - tau = -1: All pairs discordant (perfect disagreement)
Parameters
xTensor- First tensor
yTensor- Second tensor (must have same size as x)
optionsoptionalKendallTauOptionsalternative(default"two-sided"),variant("b", default, or"c") andmethod("auto", default,"exact"or"asymptotic")
Returns
[ number, number ]Tuple of [tau coefficient, p-value]
Throws
InvalidParameterErrorIf tensors have different sizes or < 2 samples, an option is invalid,methodis"exact"but there are ties, or the exact computation is too large
const x = tensor([1, 2, 3, 4, 5]);const y = tensor([1, 3, 2, 4, 5]);const [tau, p] = kendalltau(x, y); // tau = 0.8, p = 0.0833 (exact)partialcorr
function partialcorr(x: Tensor, y: Tensor, z: Tensor | Tensor[]): [ number, number ];Computes partial correlation between two variables controlling for confounders.
Partial correlation measures the linear relationship between x and y after removing the effect of one or more confounding variables (z).
Both x and y are regressed on the confounders (with an intercept) by orthogonal projection, and the Pearson correlation of the two residual vectors is returned.
Parameters
xTensor- First variable tensor (1D)
yTensor- Second variable tensor (1D, same size as x)
zTensor | Tensor[]- Confounding variable(s): a single 1D tensor or array of 1D tensors
Returns
[ number, number ]Tuple of [partial correlation coefficient, two-tailed p-value]
Throws
InvalidParameterErrorIf sizes don't match, there are fewer thanconfounders + 3samples, x or y is constant, or x or y is (numerically) an exact linear combination of the confounders
const age = tensor([25, 30, 35, 40, 45]);const income = tensor([30, 40, 55, 60, 75]);const education = tensor([12, 14, 16, 18, 20]);const [r, p] = partialcorr(income, age, education);pearsonr
function pearsonr(x: Tensor, y: Tensor, options?: CorrelationTestOptions): [ number, number ];Pearson correlation coefficient.
Measures linear correlation between two variables.
Parameters
xTensor- First tensor
yTensor- Second tensor (must have same size as x)
optionsoptionalCorrelationTestOptionsalternativehypothesis of the test (default"two-sided")
Returns
[ number, number ]Tuple of [correlation coefficient in [-1, 1], p-value]
Throws
InvalidParameterErrorIf tensors have different sizes, < 2 samples, constant input, or an invalidalternative
const x = tensor([1, 2, 3, 4, 5]);const y = tensor([2, 4, 6, 8, 10]);const [r, p] = pearsonr(x, y); // r = 1.0 (perfect linear) const [r2, pGreater] = pearsonr(x, y, { alternative: "greater" });pointbiserialr
function pointbiserialr(x: Tensor, y: Tensor, options?: CorrelationTestOptions): [ number, number ];Computes the point-biserial correlation coefficient.
Measures the correlation between a binary variable and a continuous variable. Equivalent to Pearson r where one variable is dichotomous (0/1).
Parameters
xTensor- Binary tensor (values must be 0 or 1)
yTensor- Continuous tensor (must have same size as x)
optionsoptionalCorrelationTestOptionsalternativehypothesis of the test (default"two-sided")
Returns
[ number, number ]Tuple of [correlation coefficient, p-value]
Throws
InvalidParameterErrorIf x contains non-binary values, sizes differ, < 2 samples, either input is constant (for x: all zeros or all ones), oralternativeis invalid
const gender = tensor([0, 1, 1, 0, 1, 0]);const score = tensor([72, 85, 91, 68, 88, 75]);const [r, p] = pointbiserialr(gender, score);spearmanr
function spearmanr(x: Tensor, y: Tensor, options?: CorrelationTestOptions): [ number, number ];Computes Spearman's rank correlation coefficient.
Non-parametric measure of monotonic relationship between two variables. Computed as Pearson correlation of rank values. - rho = 1: Perfect monotonic increasing relationship - rho = 0: No monotonic relationship - rho = -1: Perfect monotonic decreasing relationship
Parameters
xTensor- First tensor
yTensor- Second tensor (must have same size as x)
optionsoptionalCorrelationTestOptionsalternativehypothesis of the test (default"two-sided")
Returns
[ number, number ]Tuple of [correlation coefficient, p-value]
Throws
InvalidParameterErrorIf tensors have different sizes, < 2 samples, constant input, or an invalidalternative
const x = tensor([1, 2, 3, 4, 5]);const y = tensor([2, 4, 6, 8, 10]);const [rho, p] = spearmanr(x, y); // rho = 1.0 (perfect monotonic)bootstrap
function bootstrap(data: readonly number[], statFn: (sample: number[]) => number, options?: BootstrapOptions): BootstrapResult;Non-parametric bootstrap: resample a statistic.
Draws nResamples samples of the same size as data with replacement, evaluates statFn on each, and reports the percentile interval of those values (linear interpolation between order statistics, like numpy.percentile). If statFn returns NaN on any resample the interval is [NaN, NaN].
Parameters
datareadonly number[]- 1-D array of observations
statFn(sample: number[]) => number- Function that computes a statistic from a sample. It receives a fresh array on every call, so it may modify it.
optionsoptionalBootstrapOptions- nResamples (default 1000), seed (optional), confidenceLevel (default 0.95)
Returns
BootstrapResultObject with estimate, ci (confidence interval), and samples array
Throws
InvalidParameterErrorIfdatais empty,nResamplesis not a positive integer,confidenceLevelis not in (0, 1), orseedis not finite
const mean = (xs: number[]) => xs.reduce((a, b) => a + b, 0) / xs.length;const { estimate, ci } = bootstrap([2, 4, 4, 5, 7, 9], mean, { seed: 42 });cohenD
function cohenD(a: readonly number[], b: readonly number[]): number;Compute Cohen's d effect size between two samples.
d = (mean1 - mean2) / pooled_std
The pooled standard deviation uses the sample variance (ddof = 1) of each group. When both groups are constant the pooled standard deviation is 0: the result is 0 if the two means are equal and Infinity or -Infinity (the sign of the mean difference) otherwise.
Parameters
areadonly number[]- First sample (1-D array of numbers)
breadonly number[]- Second sample (1-D array of numbers)
Returns
numberCohen's d value
Throws
InvalidParameterErrorIf either sample has fewer than 2 observations
cohenD([1, 2, 3, 4, 5], [3, 4, 5, 6, 7]); // -2 / sqrt(2.5) ≈ -1.265geometricMean
function geometricMean(t: Tensor, axis?: AxisLike): Tensor;Computes the geometric mean along specified axis.
The geometric mean is the n-th root of the product of n values. Computed as: exp(mean(log(x))) for numerical stability. Useful for averaging ratios, growth rates, and multiplicative processes.
Parameters
tTensor- Input tensor (all values must be > 0)
axisoptionalAxisLike- Axis or axes along which to compute geometric mean (undefined = all axes)
Returns
TensorTensor containing geometric mean values
Throws
InvalidParameterErrorIf any value is <= 0IndexErrorIf axis is out of bounds
const t = tensor([1, 2, 4, 8]);geometricMean(t); // Returns ~2.83 (⁴√(1*2*4*8)) // Growth rates: 10% and 20% growthconst growth = tensor([1.1, 1.2]);geometricMean(growth); // Returns ~1.149 (average growth rate)harmonicMean
function harmonicMean(t: Tensor, axis?: AxisLike): Tensor;Computes the harmonic mean along specified axis.
The harmonic mean is the reciprocal of the arithmetic mean of reciprocals. Computed as: n / sum(1/x) Useful for averaging rates and ratios (e.g., speeds, densities).
Parameters
tTensor- Input tensor (all values must be > 0)
axisoptionalAxisLike- Axis or axes along which to compute harmonic mean (undefined = all axes)
Returns
TensorTensor containing harmonic mean values
Throws
InvalidParameterErrorIf any value is <= 0IndexErrorIf axis is out of bounds
const t = tensor([1, 2, 4]);harmonicMean(t); // Returns ~1.71 (3 / (1/1 + 1/2 + 1/4)) // Average speed: 60 mph for half distance, 40 mph for other halfconst speeds = tensor([60, 40]);harmonicMean(speeds); // Returns 48 mph (correct average)iqr
function iqr(t: Tensor, axis?: AxisLike): Tensor;Computes the interquartile range (IQR).
IQR = Q3 - Q1 = percentile(75) - percentile(25), with linear interpolation between order statistics (NumPy's default).
The IQR is a measure of spread that is less sensitive to outliers than the standard deviation.
Parameters
tTensor- Input tensor
axisoptionalAxisLike- Axis or axes along which to compute IQR (undefined = all axes)
Returns
TensorTensor containing IQR values
Throws
InvalidParameterErrorIf tensor is empty or reduction over empty axisIndexErrorIf axis is out of boundsDTypeErrorIf tensor has string dtype
const t = tensor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);iqr(t); // Returns 4.5 (a scalar tensor): Q3 (7.75) - Q1 (3.25)kurtosis
function kurtosis(t: Tensor, axis?: AxisLike, fisher?: boolean, bias?: boolean): Tensor;Parameters
tTensoraxisoptionalAxisLikefisheroptionalbooleanbiasoptionalboolean
Returns
Tensor
mean
function mean(t: Tensor, axis?: AxisLike, keepdims?: boolean): Tensor;Parameters
tTensoraxisoptionalAxisLikekeepdimsoptionalboolean
Returns
Tensor
median
function median(t: Tensor, axis?: AxisLike, keepdims?: boolean): Tensor;Parameters
tTensoraxisoptionalAxisLikekeepdimsoptionalboolean
Returns
Tensor
mode
function mode(t: Tensor, axis?: AxisLike): Tensor;Computes the mode (most frequent value) along specified axis.
The mode is the value that appears most frequently in the dataset. If multiple values have the same maximum frequency, returns the smallest value.
Parameters
tTensor- Input tensor
axisoptionalAxisLike- Axis or axes along which to compute the mode (undefined = all axes)
Returns
Tensorfloat64 tensor containing mode values. A full reduction (no axis) has shape [1]; otherwise the reduced axes are removed.
Throws
InvalidParameterErrorIf tensor is emptyIndexErrorIf axis is out of boundsDTypeErrorIf tensor has string dtype
const t = tensor([1, 2, 2, 3, 3, 3]);mode(t); // Returns tensor([3]) - most frequent value const t2 = tensor([[1, 2, 2], [3, 3, 4]]);mode(t2, 1); // Returns tensor([2, 3]) - mode of each rowmoment
function moment(t: Tensor, n: number, axis?: AxisLike): Tensor;Computes the n-th central moment about the mean.
The n-th moment is defined as: E[(X - μ)ⁿ] - n=0: Always 1 (NaN if the data contain NaN or Infinity) - n=1: Always 0 (by definition of mean; NaN if the data contain NaN or Infinity) - n=2: Population variance - n=3: Related to skewness - n=4: Related to kurtosis
Parameters
tTensor- Input tensor
nnumber- Order of the moment (must be non-negative integer)
axisoptionalAxisLike- Axis or axes along which to compute moment (undefined = all axes)
Returns
TensorTensor containing moment values
Throws
InvalidParameterErrorIf n is not a non-negative integer, the tensor is empty, or the reduction is over an empty axisIndexErrorIf axis is out of boundsDTypeErrorIf tensor has string dtype
const t = tensor([1, 2, 3, 4, 5]);moment(t, 1); // Returns 0 (first moment about mean)moment(t, 2); // Returns 2 (population variance)moment(t, 3); // Returns 0 (third moment of a symmetric sample)percentile
function percentile(t: Tensor, q: number | number[], axis?: AxisLike): Tensor;Computes percentiles along specified axes.
Percentiles are quantiles expressed as percentages (0-100 instead of 0-1). This is a convenience wrapper around quantile().
Parameters
tTensor- Input tensor
qnumber | number[]- Percentile(s) to compute, in range [0, 100] (50 = median)
axisoptionalAxisLike- Axis or axes along which to compute percentiles (undefined = all axes)
Returns
TensorTensor containing percentile values
Throws
InvalidParameterErrorIf q is not in [0, 100], tensor is empty, or reduction over empty axisIndexErrorIf axis is out of bounds
const t = tensor([1, 2, 3, 4, 5]);percentile(t, 50); // Returns tensor([3]) - medianpercentile(t, [25, 75]); // Returns tensor([2, 4]) - quartilespercentile(t, 95); // Returns tensor([4.8]) - 95th percentilequantile
function quantile(t: Tensor, q: number | number[], axis?: AxisLike): Tensor;Computes quantiles along specified axes.
Quantiles are cut points dividing the range of a probability distribution. Uses linear interpolation between data points (NumPy's default linear method).
Parameters
tTensor- Input tensor
qnumber | number[]- Quantile(s) to compute, in range [0, 1] (0.5 = median)
axisoptionalAxisLike- Axis or axes along which to compute quantiles (undefined = all axes)
Returns
Tensorfloat64 tensor with one leading entry per quantile: shape [q.length] for a full reduction, [q.length, ...reducedShape] when axis is given (q.length is 1 for a scalar q)
Throws
InvalidParameterErrorIf q is not in [0, 1], tensor is empty, or reduction over empty axisIndexErrorIf axis is out of boundsDTypeErrorIf tensor has string dtype
const t = tensor([1, 2, 3, 4, 5]);quantile(t, 0.5); // Returns tensor([3]) - medianquantile(t, [0.25, 0.75]); // Returns tensor([2, 4]) - quartilesquantile(t, 0.95); // Returns tensor([4.8]) - 95th percentilesem
function sem(t: Tensor, axis?: AxisLike, ddof?: number): Tensor;Computes the standard error of the mean (SEM).
SEM = std(x, ddof=1) / sqrt(n)
The SEM quantifies how precisely the sample mean estimates the population mean. Smaller SEM indicates a more precise estimate.
Parameters
tTensor- Input tensor
axisoptionalAxisLike- Axis or axes along which to compute SEM (undefined = all axes)
ddofoptionalnumber- Delta degrees of freedom for std computation (default: 1)
Returns
TensorTensor containing SEM values
Throws
InvalidParameterErrorIf tensor is empty, the reduction is over an empty axis, or it has no more thanddofobservationsIndexErrorIf axis is out of boundsDTypeErrorIf tensor has string dtype
const t = tensor([1, 2, 3, 4, 5]);sem(t); // Returns std(t, ddof=1) / sqrt(5) ≈ 0.7071skewness
function skewness(t: Tensor, axis?: AxisLike, bias?: boolean): Tensor;Parameters
tTensoraxisoptionalAxisLikebiasoptionalboolean
Returns
Tensor
std
function std(t: Tensor, axis?: AxisLike, keepdims?: boolean, ddof?: number): Tensor;Parameters
tTensoraxisoptionalAxisLikekeepdimsoptionalbooleanddofoptionalnumber
Returns
Tensor
trimMean
function trimMean(t: Tensor, proportiontocut: number, axis?: AxisLike): Tensor;Computes the trimmed mean (mean after removing outliers from both tails).
Removes a specified proportion of extreme values from both ends before computing mean. Less sensitive to outliers than the regular mean, less extreme than the median. The number of values removed from each tail is floor(n * proportiontocut), as in scipy.stats.trim_mean.
Parameters
tTensor- Input tensor
proportiontocutnumber- Fraction to cut from each tail, in range [0, 0.5)
axisoptionalAxisLike- Axis or axes along which to compute trimmed mean (undefined = all axes)
Returns
Tensorfloat64 tensor of trimmed means. For a full reduction (no axis) the result has shape [1]; otherwise the reduced axes are removed.
Throws
InvalidParameterErrorIf proportiontocut is not in [0, 0.5), tensor is empty, or reduction over empty axisIndexErrorIf axis is out of boundsDTypeErrorIf tensor has string dtype
const t = tensor([1, 2, 3, 4, 5, 100]); // 100 is outliermean(t); // Returns ~19.17 (affected by outlier)trimMean(t, 0.2); // Returns 3.5 (removes 1 and 100)trimMean(t, 0.1); // Returns ~19.17 (floor(6 * 0.1) = 0 values removed)variance
function variance(t: Tensor, axis?: AxisLike, keepdims?: boolean, ddof?: number): Tensor;Parameters
tTensoraxisoptionalAxisLikekeepdimsoptionalbooleanddofoptionalnumber
Returns
Tensor
zscore
function zscore(t: Tensor, ddof?: number, axis?: AxisLike): Tensor;Compute the z-score of each element relative to the sample mean and std.
z = (x - mean) / std
Without axis the mean and standard deviation are taken over every element (note that scipy.stats.zscore defaults to axis=0; pass axis to get that behavior). The output always has the same shape as the input. A slice with zero standard deviation maps to zeros instead of NaN.
Parameters
tTensor- Input tensor
ddofoptionalnumber- Delta degrees of freedom for std (default 0)
axisoptionalAxisLike- Axis or axes along which to standardize (undefined = all elements)
Returns
Tensorfloat64 tensor of z-scores with the same shape as t
Throws
InvalidParameterErrorIf the tensor is empty,ddofis negative or not finite, orddofis not smaller than the number of elements being standardized togetherIndexErrorIf axis is out of boundsDTypeErrorIf tensor has string dtype
zscore(tensor([1, 2, 3, 4, 5])); // (x - 3) / sqrt(2)zscore(tensor([[1, 2], [3, 6]]), 0, 0); // standardize each columnimport { corrcoef, kendalltau, mean, percentile, pearsonr, spearmanr, std, zscore,} from "deepbox/stats";import { tensor } from "deepbox/ndarray"; const x = tensor([1, 2, 3, 4, 5]);const y = tensor([2, 4, 3, 8, 7]); console.log(mean(x).toString(), std(x).toString(), std(x, { ddof: 1 }).toString());console.log(percentile(x, 90).toString());console.log(zscore(x).toString());console.log(corrcoef(x, y).toString()); // 2 x 2 matrix for the two variables const [r, p] = pearsonr(x, y, { alternative: "greater" });console.log(r, p);console.log(spearmanr(x, y), kendalltau(x, y));Found a mistake? Open an issue.