or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

apidiff.mdconstraints.mdebnf.mderrors.mdevent.mdgorelease.mdindex.mdio-i2c.mdio-spi.mdjsonrpc2.mdmaps.mdmmap.mdmodgraphviz.mdrand.mdshiny.mdslices.mdslog.mdstats.mdsumdb.mdtrace.mdtxtar.mdtypeparams.mdutf8string.md
tile.json

stats.mddocs/

golang.org/x/exp/stats

The stats package provides basic descriptive statistics functions for statistical analysis. It is designed to offer common, everyday statistical functions that would be explained in a typical high school statistics course.

The package aims to balance performance and accuracy, though some amount of error is inevitable in floating-point computations. The underlying implementations may change, resulting in small changes in their results from version to version. For applications requiring particular guarantees on accuracy, overflow behavior, or version stability, a more specialized statistics implementation should be used.

Package Information

  • Package Name: golang.org/x/exp/stats
  • Package Type: golang (Go module)
  • Language: Go
  • Installation: go get golang.org/x/exp

Core Imports

import (
    "golang.org/x/exp/stats"
)

Basic Usage

package main

import (
    "fmt"
    "golang.org/x/exp/stats"
)

func main() {
    // Sample data
    values := []float64{1.5, 2.3, 3.1, 4.2, 5.0}

    // Calculate mean
    mean := stats.Mean(values)
    fmt.Printf("Mean: %.2f\n", mean)

    // Calculate mean and standard deviation
    mean, stdDev := stats.MeanAndStdDev(values)
    fmt.Printf("Mean: %.2f, StdDev: %.2f\n", mean, stdDev)

    // Calculate median
    median := stats.Median(values)
    fmt.Printf("Median: %.2f\n", median)

    // Calculate quantiles
    quantiles := stats.Quantiles(values, 0.25, 0.5, 0.75)
    fmt.Printf("25th percentile: %.2f\n", quantiles[0])
    fmt.Printf("50th percentile: %.2f\n", quantiles[1])
    fmt.Printf("75th percentile: %.2f\n", quantiles[2])
}

Capabilities

Mean Calculation

Computes the arithmetic mean of a dataset.

func Mean[F ~float64](values []F) F

Description: Mean returns the arithmetic mean of the values in the slice. The function does not modify the input array.

Behavior:

  • Panics if values is an empty slice
  • If values contains NaN, returns NaN
  • If values contains both Inf and -Inf, returns NaN
  • If values contains only Inf, returns Inf
  • If values contains only -Inf, returns -Inf

Example:

package main

import (
    "fmt"
    "golang.org/x/exp/stats"
)

func main() {
    values := []float64{10, 20, 30, 40, 50}
    mean := stats.Mean(values)
    fmt.Printf("Mean: %.2f\n", mean) // Output: Mean: 30.00

    // Works with any type that underlies float64
    floats := []float32{1.5, 2.5, 3.5}
    mean32 := stats.Mean(floats)
    fmt.Printf("Mean: %.2f\n", mean32) // Output: Mean: 2.50
}

Mean and Standard Deviation

Computes both the arithmetic mean and sample standard deviation in a single operation.

func MeanAndStdDev[F ~float64](values []F) (F, F)

Description: MeanAndStdDev returns the arithmetic mean and sample standard deviation of the input values. The standard deviation is calculated as the sample standard deviation and is only meaningful when len(values) > 1. The function does not modify the input array.

Behavior:

  • Panics if values is an empty slice
  • If values contains NaN, returns (NaN, NaN)
  • If values contains both Inf and -Inf, returns (NaN, Inf)
  • If values contains only Inf, returns (Inf, Inf)
  • If values contains only -Inf, returns (-Inf, Inf)

Example:

package main

import (
    "fmt"
    "golang.org/x/exp/stats"
)

func main() {
    // Student test scores
    scores := []float64{85, 90, 78, 92, 88, 76, 95}

    mean, stdDev := stats.MeanAndStdDev(scores)
    fmt.Printf("Mean Score: %.2f\n", mean)           // Mean Score: 86.29
    fmt.Printf("Standard Deviation: %.2f\n", stdDev) // Standard Deviation: 6.39

    // Single value - standard deviation undefined but still computed
    single := []float64{42.0}
    mean, stdDev = stats.MeanAndStdDev(single)
    fmt.Printf("Mean: %.2f, StdDev: %.2f\n", mean, stdDev)
}

Median Calculation

Computes the middle value of a sorted dataset.

func Median[F ~float64](values []F) F

Description: Median returns the median of the values in the slice. For odd-length slices, it returns the middle value. For even-length slices, it returns the average of the two middle values. The function does not modify the input array but may perform faster if the slice is already sorted.

Behavior:

  • Panics if values is an empty slice
  • If values contains NaN, returns NaN
  • -Inf is treated as smaller than all other values
  • Inf is treated as larger than all other values
  • -0.0 is treated as smaller than 0.0

Example:

package main

import (
    "fmt"
    "golang.org/x/exp/stats"
)

func main() {
    // Odd number of values
    oddValues := []float64{3, 1, 4, 1, 5, 9, 2}
    median := stats.Median(oddValues)
    fmt.Printf("Median: %.2f\n", median) // Output: Median: 3.00

    // Even number of values
    evenValues := []float64{10, 20, 30, 40}
    median = stats.Median(evenValues)
    fmt.Printf("Median: %.2f\n", median) // Output: Median: 25.00

    // Already sorted data (faster)
    sorted := []float64{1, 2, 3, 4, 5}
    median = stats.Median(sorted)
    fmt.Printf("Median: %.2f\n", median) // Output: Median: 3.00
}

Quantiles Calculation

Computes quantiles (percentiles) of a dataset.

func Quantiles[F, Q ~float64](values []F, quantiles ...Q) []F

Description: Quantiles returns a sequence of quantiles of the input values. The returned slice has the same length as the quantiles input slice, with elements corresponding one-to-one to the input quantiles. A quantile of 0 corresponds to the minimum value, and a quantile of 1 corresponds to the maximum value. A quantile of 0.5 is equivalent to the median.

Parameters:

  • values: The input data slice for which to compute quantiles
  • quantiles: Variable number of quantile values (must be in range [0, 1])

Return Value: A slice of floats representing the quantile values, with length equal to the quantiles input

Behavior:

  • Panics if values is an empty slice
  • Panics if any quantile is not in the interval [0, 1]
  • If values contains NaN, returns [NaN, ..., NaN]
  • -Inf is treated as smaller than all other values
  • Inf is treated as larger than all other values
  • -0.0 is treated as smaller than 0.0
  • May perform asymptotically faster and allocate less memory if the slice is already sorted

Example:

package main

import (
    "fmt"
    "golang.org/x/exp/stats"
)

func main() {
    // Dataset with 100 values
    data := []float64{
        1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
        11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
        21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
        31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
        41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
        51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
        61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
        71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
        81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
        91, 92, 93, 94, 95, 96, 97, 98, 99, 100,
    }

    // Calculate quartiles (25th, 50th, 75th percentiles)
    quartiles := stats.Quantiles(data, 0.25, 0.5, 0.75)
    fmt.Printf("25th percentile (Q1): %.2f\n", quartiles[0])
    fmt.Printf("50th percentile (Q2/Median): %.2f\n", quartiles[1])
    fmt.Printf("75th percentile (Q3): %.2f\n", quartiles[2])

    // Calculate deciles
    deciles := stats.Quantiles(data, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9)
    for i, q := range deciles {
        fmt.Printf("%.0f%% percentile: %.2f\n", (float64(i)+1)*10, q)
    }

    // Min and max
    minMax := stats.Quantiles(data, 0, 1)
    fmt.Printf("Min: %.2f, Max: %.2f\n", minMax[0], minMax[1])
}

Advanced Usage Patterns

Computing Percentile Ranks

package main

import (
    "fmt"
    "golang.org/x/exp/stats"
)

func main() {
    // Test scores
    scores := []float64{65, 72, 78, 82, 88, 91, 95, 98}

    // Get percentile information
    q1, median, q3 := stats.Quantiles(scores, 0.25, 0.5, 0.75)
    mean, stdDev := stats.MeanAndStdDev(scores)

    fmt.Printf("Q1 (25%%): %.1f\n", q1)
    fmt.Printf("Median (50%%): %.1f\n", median)
    fmt.Printf("Q3 (75%%): %.1f\n", q3)
    fmt.Printf("Mean: %.1f ± %.1f\n", mean, stdDev)
    fmt.Printf("IQR (Interquartile Range): %.1f\n", q3-q1)
}

Statistical Analysis of Measurement Data

package main

import (
    "fmt"
    "golang.org/x/exp/stats"
)

func main() {
    // Measurements of a process
    measurements := []float64{
        9.8, 9.9, 10.0, 10.1, 9.95, 10.05, 9.98, 10.02,
        9.99, 10.01, 10.0, 9.97,
    }

    mean, stdDev := stats.MeanAndStdDev(measurements)
    median := stats.Median(measurements)

    fmt.Printf("Process Statistics:\n")
    fmt.Printf("  Mean: %.3f\n", mean)
    fmt.Printf("  Median: %.3f\n", median)
    fmt.Printf("  Std Dev: %.4f\n", stdDev)
    fmt.Printf("  95%% CI: [%.3f, %.3f]\n", mean-1.96*stdDev, mean+1.96*stdDev)
}

Generic Type Support

All functions in the stats package use generic type parameters that work with any type that underlies float64. This allows seamless use with custom float types:

package main

import (
    "fmt"
    "golang.org/x/exp/stats"
)

type Temperature float64  // Custom type

func main() {
    temps := []Temperature{98.6, 99.1, 98.9, 100.2, 98.5}
    mean := stats.Mean(temps)
    fmt.Printf("Mean temperature: %.1f\n", mean)

    // Works directly with custom types without conversion
    median := stats.Median(temps)
    fmt.Printf("Median temperature: %.1f\n", median)
}

Special Values Handling

The stats package handles special floating-point values according to IEEE 754 rules:

  • NaN (Not a Number): Any operation on data containing NaN typically returns NaN
  • Inf (Positive Infinity): Treated as the largest value
  • -Inf (Negative Infinity): Treated as the smallest value
  • -0.0 (Negative Zero): Treated as smaller than positive 0.0

Common Errors and Pitfalls

  1. Empty Slice Panic: All functions will panic if called with an empty slice

    // This will panic
    empty := []float64{}
    stats.Mean(empty)  // panic
  2. Invalid Quantile Values: Quantiles must be between 0 and 1

    // This will panic
    stats.Quantiles(values, 1.5)  // panic: quantile outside [0, 1]
  3. NaN Propagation: If your data contains NaN, most results will be NaN

    values := []float64{1, 2, math.NaN(), 4}
    mean := stats.Mean(values)  // result: NaN

Type Constraints

All functions use the following generic constraints:

// F ~float64 - Any type that underlies float64 (like custom types)
// Q ~float64 - For quantile parameters, any type that underlies float64

This allows the functions to work with:

  • float64 directly
  • Custom types defined as type MyFloat float64
  • Any other type where the underlying type is float64

Performance Considerations

  • Median: May allocate memory for sorting if input is not sorted. Pre-sorted data can be more efficient.
  • Quantiles: Similar to Median; benefits from pre-sorted data.
  • Mean: Single pass through data, optimal performance.
  • MeanAndStdDev: Efficient two-pass computation, better than calling Mean and computing StdDev separately.

Implementation Notes

The stats package prioritizes correctness and usability over comprehensive statistical features. For applications requiring:

  • Advanced statistical methods (hypothesis testing, confidence intervals, etc.)
  • Specialized distributions (normal, binomial, etc.)
  • Maximum numerical stability guarantees
  • Deterministic version-to-version behavior

Consider using specialized statistics libraries designed for those specific needs.