Skip to content

Polars.NETThe High-Performance DataFrame Library

Rust Core. Arrow Memory. Native Speed.

Unified Across Paradigms ​

Write queries in the style most natural to your project. Polars.NET executes C# Fluent calls, F# functional pipelines, C# LINQ syntax, and F# computation expressions with identical, zero-copy native performance:

csharp
using Polars.CSharp;
using static Polars.CSharp.Polars;

// Ingest from strongly-typed records or anonymous objects
var df = DataFrame.FromColumns(new
{
    Date = new[] { "2023-01-01", "2023-01-01", "2023-01-02" },
    City = new[] { "London", "Manchester", "London" },
    Temperature = new[] { 10.5, 9.0, 12.1 },
    Rain = new[] { true, true, false }
}).WithColumn(Col("Date").Str.ToDate("%Y-%m-%d"));

// Filter, GroupBy & Aggregate with multi-threaded SIMD execution
var result = df.Lazy()
    .Filter(Col("Temperature") > 9.5)
    .GroupBy("City")
    .Agg(
        Col("Temperature").Mean().Alias("Avg_Temperature"),
        Col("Temperature").Count().Alias("Record_Count")
    )
    .Sort("Avg_Temperature", descending: true)
    .Collect();
fsharp
open Polars.FSharp

type Weather = { Date: string; City: string; Temperature: float; Rain: bool }

let data = [
    { Date="2023-01-01"; City="London";     Temperature=10.5; Rain=true }
    { Date="2023-01-01"; City="Manchester"; Temperature=9.0;  Rain=true }
    { Date="2023-01-02"; City="London";     Temperature=12.1; Rain=false }
]

// Idiomatic functional pipelines with pl.* combinators
let result =
    DataFrame.ofRecords data
    |> DataFrame.withColumn (pl.col("Date").Str.ToDate "%Y-%m-%d")
    |> DataFrame.filter (pl.col "Temperature" .> pl.lit 9.5)
    |> DataFrame.groupBy [ pl.col "City" ]
    |> DataFrame.agg [
        pl.col("Temperature").Mean().Alias "Avg_Temperature"
        pl.col("Temperature").Count().Alias "Record_Count"
    ]
    |> DataFrame.sortDescending [ pl.col "Avg_Temperature" ]
csharp
using Polars.CSharp;
using Polars.CSharp.Linq;

// Standard C# LINQ with 100% Native Pushdown to the Rust engine
var result = (from r in df.AsQueryable<WeatherRecord>()
              where r.Temperature > 9.5
              group r by r.City into g
              select new {
                  City = g.Key,
                  Avg_Temperature = g.Average(x => x.Temperature),
                  Record_Count = g.Count()
              })
              .ToDataFrame()
              .Sort("Avg_Temperature", descending: true);
fsharp
open Polars.FSharp
open Polars.FSharp.Query

// Native F# query { } computation expression
let result =
    query {
        for r in df.AsQueryable<Weather>() do
        where (r.Temperature > 9.5)
        groupValBy r r.City into g
        select {|
            City = g.Key
            Avg_Temperature = g.Average(fun x -> x.Temperature)
            Record_Count = g.Count()
        |}
    }
    |> Query.toDataFrame
    |> DataFrame.sortDescending [ pl.col "Avg_Temperature" ]

Output ​

Aggregated DataFrame Output
Polars DataFrame: (1 rows, 3 columns)
CitystrAvg_Temperaturef64Record_Countu32
London11.32

Why Polars.NET? ​

FeatureStandard .NET DataFramesPolars.NET
Execution CoreInterpreted managed loopsMulti-threaded vectorized Rust SIMD
Memory ModelManaged object allocations (GC pressure)Arrow columnar layout with zero-copy FFI
Query OptimizationNone (client-side execution)Logical plan optimization, Predicate & Projection pushdown
Out-of-Core ProcessingOut of Memory (OOM) on large filesStreaming engine & Chunked memory
Language ParadigmsBasic C# collection methodsC# Fluent API, F# Pipelines, C# LINQ, and F# Query CE
Lakehouse & Big DataRequires Spark / JVM wrappersNative Delta Lake ACID storage, ADBC, & Arrow IPC

Ready to build blazingly fast data pipelines? Read the Quick Start Guide or explore the Core Concepts.


Built on Polars ​

Polars.NET brings the blazing speed, Arrow memory layout, and query optimization of the world-class Polars DataFrame engine to the .NET ecosystem. We express our deepest gratitude to Ritchie Vink and the entire Polars open-source community for their pioneering work on high-performance columnar data processing.

Released under the MIT License. Powered by the Polars Rust core & Apache Arrow.