Skip to main content

High-performance LOWESS smoothing for Rust, Python, and R.

Project description

LOWESS Project

License Docs Crates.io PyPI Conda R-universe

The fastest, most robust, and most feature-complete language-agnostic LOWESS (Locally Weighted Scatterplot Smoothing) implementation for Rust, Python, and R.

[!IMPORTANT]

The lowess-project contains a complete ecosystem for LOWESS smoothing:

  • lowess - Core single-threaded Rust implementation with no_std support
  • fastLowess - Parallel CPU and GPU-accelerated Rust wrapper with ndarray integration
  • Python bindings - PyO3-based Python package
  • R bindings - extendr-based R package

LOESS vs. LOWESS

Feature LOESS (This Crate) LOWESS
Polynomial Degree Linear, Quadratic, Cubic, Quartic Linear (Degree 1)
Dimensions Multivariate (n-D support) Univariate (1-D only)
Flexibility High (Distance metrics) Standard
Complexity Higher (Matrix inversion) Lower (Weighted average/slope)

[!TIP] Note: For a LOESS implementation, use loess-project.


Documentation

[!NOTE]

📚 View the full documentation

Why this package?

Speed

The lowess project crushes the competition in terms of speed, wether in single-threaded or multi-threaded parallel execution.

Speedup relative to Python's statsmodels.lowess (higher is better):

Category statsmodels R (stats) Serial Parallel GPU
Clustered 163ms 83× 203× 433× 32×
Constant Y 134ms 92× 212× 410× 18×
Delta (large–none) 105ms 16×
Extreme Outliers 489ms 106× 201× 388× 29×
Financial (500–10K) 106ms 105× 252× 293× 12×
Fraction (0.05–0.67) 221ms 104× 228× 391× 22×
Genomic (1K–50K) 1833ms 20× 95×
High Noise 435ms 133× 134× 375× 32×
Iterations (0–10) 204ms 115× 224× 386× 18×
Scale (1K–50K) 1841ms 264× 487× 581× 98×
Scientific (500–10K) 167ms 109× 205× 314× 15×
Scale Large* (100K–2M) 1.4× 0.3×

*Scale Large benchmarks are relative to Serial (statsmodels cannot handle these sizes)

The numbers are the average across a range of scenarios for each category (e.g., Delta from none, to small, medium, and large).

Robustness

This implementation is more robust than R's lowess and Python's statsmodels due to two key design choices:

MAD-Based Scale Estimation:

For robustness weight calculations, this crate uses Median Absolute Deviation (MAD) for scale estimation:

s = median(|r_i - median(r)|)

In contrast, statsmodels and R's lowess uses the median of absolute residuals (MAR):

s = median(|r_i|)
  • MAD is a breakdown-point-optimal estimator—it remains valid even when up to 50% of data are outliers.
  • The median-centering step removes asymmetric bias from residual distributions.
  • MAD provides consistent outlier detection regardless of whether residuals are centered around zero.

Boundary Padding:

This crate applies a range of different boundary policies at dataset edges:

  • Extend: Repeats edge values to maintain local neighborhood size.
  • Reflect: Mirrors data symmetrically around boundaries.
  • Zero: Pads with zeros (useful for signal processing).
  • NoBoundary: Original Cleveland behavior

statsmodels and R's lowess do not apply boundary padding, which can lead to:

  • Biased estimates near boundaries due to asymmetric local neighborhoods.
  • Increased variance at the edges of the smoothed curve.

Features

A variety of features, supporting a range of use cases:

Feature This package statsmodels R (stats)
Kernel 7 options only Tricube only Tricube
Robustness Weighting 3 options only Huber only Huber
Scale Estimation 2 options only MAR only MAR
Boundary Padding 4 options no padding no padding
Zero Weight Fallback 3 options no no
Auto Convergence yes no no
Online Mode yes no no
Streaming Mode yes no no
Confidence Intervals yes no no
Prediction Intervals yes no no
Cross-Validation 2 options no no
Parallel Execution yes no no
GPU Acceleration yes* no no
no-std Support yes no no

* GPU acceleration is currently in beta and may not be available on all platforms.

Validation

All implementations are numerical twins of R's lowess:

Aspect Status Details
Accuracy ✅ EXACT MATCH Max diff < 1e-12 across all scenarios
Consistency ✅ PERFECT Multiple scenarios pass with strict tolerance
Robustness ✅ VERIFIED Robust smoothing matches R exactly

Installation

Currently available for R, Python, and Rust:

R (from R-universe, recommended):

install.packages("rfastlowess", repos = "https://thisisamirv.r-universe.dev")

Python (from PyPI):

pip install fastlowess

Or from conda-forge:

conda install -c conda-forge fastlowess

Rust (lowess, no_std compatible):

[dependencies]
lowess = "0.99"

Rust (fastLowess, parallel + GPU):

[dependencies]
fastLowess = { version = "0.99", features = ["cpu"] }

Quick Example

R:

library(rfastlowess)

x <- c(1, 2, 3, 4, 5)
y <- c(2.0, 4.1, 5.9, 8.2, 9.8)

result <- fastlowess(x, y, fraction = 0.5, iterations = 3)
print(result$y)

Python:

import fastlowess as fl
import numpy as np

x = np.array([1.0, 2.0, 3.0, 4.0, 5.0])
y = np.array([2.0, 4.1, 5.9, 8.2, 9.8])

result = fl.smooth(x, y, fraction=0.5, iterations=3)
print(result["y"])

Rust:

use lowess::prelude::*;

let x = vec![1.0, 2.0, 3.0, 4.0, 5.0];
let y = vec![2.0, 4.1, 5.9, 8.2, 9.8];

let model = Lowess::new()
    .fraction(0.5)
    .iterations(3)
    .adapter(Batch)
    .build()?;

let result = model.fit(&x, &y)?;
println!("{}", result);

API Reference

R:

fastlowess(
    x, y,
    fraction = 0.5,
    iterations = 3L,
    delta = 0.01,
    weight_function = "tricube",
    robustness_method = "bisquare",
    zero_weight_fallback = "use_local_mean",
    boundary_policy = "extend",
    confidence_intervals = 0.95,
    prediction_intervals = 0.95,
    return_diagnostics = TRUE,
    return_residuals = TRUE,
    return_robustness_weights = TRUE,
    cv_fractions = c(0.3, 0.5, 0.7),
    cv_method = "kfold",
    cv_k = 5L,
    auto_converge = 1e-4,
    parallel = TRUE
)

Python:

fastlowess.smooth(
    x, y,
    fraction=0.5,
    iterations=3,
    delta=0.01,
    weight_function="tricube",
    robustness_method="bisquare",
    zero_weight_fallback="use_local_mean",
    boundary_policy="extend",
    confidence_intervals=0.95,
    prediction_intervals=0.95,
    return_diagnostics=True,
    return_residuals=True,
    return_robustness_weights=True,
    cv_fractions=[0.3, 0.5, 0.7],
    cv_method="kfold",
    cv_k=5,
    auto_converge=1e-4,
    parallel=True
)

Rust:

Lowess::new()
    .fraction(0.5)              // Smoothing span (0, 1]
    .iterations(3)              // Robustness iterations
    .delta(0.01)                // Interpolation threshold
    .weight_function(Tricube)   // Kernel selection
    .robustness_method(Bisquare)
    .zero_weight_fallback(UseLocalMean)
    .boundary_policy(Extend)
    .confidence_intervals(0.95)
    .prediction_intervals(0.95)
    .return_diagnostics()
    .return_residuals()
    .return_robustness_weights()
    .cross_validate(KFold(5, &[0.3, 0.5, 0.7]).seed(123))
    .auto_converge(1e-4)
    .adapter(Batch)             // or Streaming, Online
    .parallel(true)             // fastLowess only
    .backend(CPU)               // fastLowess only: CPU or GPU
    .build()?;

Result Structure

R:

result$x, result$y, result$standard_errors
result$confidence_lower, result$confidence_upper
result$prediction_lower, result$prediction_upper
result$residuals, result$robustness_weights
result$diagnostics, result$iterations_used
result$fraction_used, result$cv_scores

Python:

result.x, result.y, result.standard_errors
result.confidence_lower, result.confidence_upper
result.prediction_lower, result.prediction_upper
result.residuals, result.robustness_weights
result.diagnostics, result.iterations_used
result.fraction_used, result.cv_scores

Rust:

pub struct LowessResult<T> {
    pub x: Vec<T>,                           // Sorted x values
    pub y: Vec<T>,                           // Smoothed y values
    pub standard_errors: Option<Vec<T>>,
    pub confidence_lower: Option<Vec<T>>,
    pub confidence_upper: Option<Vec<T>>,
    pub prediction_lower: Option<Vec<T>>,
    pub prediction_upper: Option<Vec<T>>,
    pub residuals: Option<Vec<T>>,
    pub robustness_weights: Option<Vec<T>>,
    pub diagnostics: Option<Diagnostics<T>>,
    pub iterations_used: Option<usize>,
    pub fraction_used: T,
    pub cv_scores: Option<Vec<T>>,
}

Contributing

Contributions are welcome! Please see the CONTRIBUTING.md file for more information.

License

Licensed under either of:

at your option.

References

  • Cleveland, W.S. (1979). "Robust Locally Weighted Regression and Smoothing Scatterplots". JASA.
  • Cleveland, W.S. (1981). "LOWESS: A Program for Smoothing Scatterplots". The American Statistician.

Citation

If you use this software in your research, please cite it using the CITATION.cff file or the BibTeX entry below:

@software{lowess_project,
  author = {Valizadeh, Amir},
  title = {LOWESS Project: High-Performance Locally Weighted Scatterplot Smoothing},
  year = {2026},
  url = {https://github.com/thisisamirv/lowess-project},
  license = {MIT OR Apache-2.0}
}

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fastlowess-0.99.7.tar.gz (117.7 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

fastlowess-0.99.7-cp38-abi3-win_amd64.whl (324.7 kB view details)

Uploaded CPython 3.8+Windows x86-64

fastlowess-0.99.7-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (451.9 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ x86-64

fastlowess-0.99.7-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (436.9 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ ARM64

fastlowess-0.99.7-cp38-abi3-macosx_11_0_arm64.whl (399.7 kB view details)

Uploaded CPython 3.8+macOS 11.0+ ARM64

fastlowess-0.99.7-cp38-abi3-macosx_10_12_x86_64.whl (425.5 kB view details)

Uploaded CPython 3.8+macOS 10.12+ x86-64

File details

Details for the file fastlowess-0.99.7.tar.gz.

File metadata

  • Download URL: fastlowess-0.99.7.tar.gz
  • Upload date:
  • Size: 117.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for fastlowess-0.99.7.tar.gz
Algorithm Hash digest
SHA256 d0b075660b4cc5eb392f13e1a6d0602e07b230880ea0606f8fb92c07b84ac517
MD5 4e7e4c48fa1bb76fbf6f59e05d1b33d3
BLAKE2b-256 6dd5bd6d1af9bec5063359a7eb5b7a415e63d259392281c2ee7ce4edff5ddca7

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastlowess-0.99.7.tar.gz:

Publisher: release.yml on thisisamirv/lowess-project

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fastlowess-0.99.7-cp38-abi3-win_amd64.whl.

File metadata

  • Download URL: fastlowess-0.99.7-cp38-abi3-win_amd64.whl
  • Upload date:
  • Size: 324.7 kB
  • Tags: CPython 3.8+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for fastlowess-0.99.7-cp38-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 9293f832dc0fa5066f3987aed6f53bdfeef12ba56c128b79e68bd9969c6c8de7
MD5 bc94db5da87ca199233e4b1b9849183f
BLAKE2b-256 dbc95904bff76ef64e2c6741ea92004cc25df735711f2e16b49669234d956850

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastlowess-0.99.7-cp38-abi3-win_amd64.whl:

Publisher: release.yml on thisisamirv/lowess-project

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fastlowess-0.99.7-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for fastlowess-0.99.7-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 0f979aa3d6de27ec00ef3ab25dd997570607ac4016c71886c167040cafd370f8
MD5 a6dd82795a56eec5c83d1fd31ffcb4b8
BLAKE2b-256 b5b28fa562a99d9e4bd13b1b4c62b3ee45da1079934ac72993ba97bb3872afb8

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastlowess-0.99.7-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on thisisamirv/lowess-project

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fastlowess-0.99.7-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for fastlowess-0.99.7-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 aa411b409149da911c6d57c30a62fa049daca64f3961a640f6c4d4240be42a28
MD5 290df34f75685425a17b5cf15af58eea
BLAKE2b-256 6d45acffa638ff17260ba30767db137d57b0e5c7c6bde3b28136261bd96e0158

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastlowess-0.99.7-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on thisisamirv/lowess-project

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fastlowess-0.99.7-cp38-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for fastlowess-0.99.7-cp38-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 fa228e84be0e52c5f9327dc8697b7604c8788564c97e10fab29c40a8612c7dbd
MD5 00dd9bd178e0c4c807fbdca9f5f93838
BLAKE2b-256 897424b24dc90e57d4fb017f73641d514c080fce9f9fcd178aaa58885db7b753

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastlowess-0.99.7-cp38-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on thisisamirv/lowess-project

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fastlowess-0.99.7-cp38-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for fastlowess-0.99.7-cp38-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 a50570457c564a6ff7fdd9cd8747c460d40657c22dd0e2fa9bf8736e9a58b803
MD5 c8a87acb2248d3c2d20fe68bf4e09f27
BLAKE2b-256 c1b061dbeef1a82eb3ad77471746d87ec812ff0401d1b30f14099c99adcc2af4

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastlowess-0.99.7-cp38-abi3-macosx_10_12_x86_64.whl:

Publisher: release.yml on thisisamirv/lowess-project

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page