Experimental and deprecated Go packages for various functionality
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.
go get golang.org/x/expimport (
"golang.org/x/exp/stats"
)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])
}Computes the arithmetic mean of a dataset.
func Mean[F ~float64](values []F) FDescription: Mean returns the arithmetic mean of the values in the slice. The function does not modify the input array.
Behavior:
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
}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:
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)
}Computes the middle value of a sorted dataset.
func Median[F ~float64](values []F) FDescription: 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:
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
}Computes quantiles (percentiles) of a dataset.
func Quantiles[F, Q ~float64](values []F, quantiles ...Q) []FDescription: 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 quantilesquantiles: 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:
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])
}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)
}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)
}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)
}The stats package handles special floating-point values according to IEEE 754 rules:
Empty Slice Panic: All functions will panic if called with an empty slice
// This will panic
empty := []float64{}
stats.Mean(empty) // panicInvalid Quantile Values: Quantiles must be between 0 and 1
// This will panic
stats.Quantiles(values, 1.5) // panic: quantile outside [0, 1]NaN Propagation: If your data contains NaN, most results will be NaN
values := []float64{1, 2, math.NaN(), 4}
mean := stats.Mean(values) // result: NaNAll 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 float64This allows the functions to work with:
float64 directlytype MyFloat float64The stats package prioritizes correctness and usability over comprehensive statistical features. For applications requiring:
Consider using specialized statistics libraries designed for those specific needs.
Install with Tessl CLI
npx tessl i tessl/go-golang-org-x-exp