Learn Polars

Fast multi-threaded DataFrames with a lazy, optimizing query engine

20 lessons · 4 hours · 4 levels · covers Polars 2.0

Polars is a DataFrame library written in Rust with a Python API, built on the Apache Arrow memory format. Its expression API and lazy query engine let it optimize whole queries, use every CPU core and process data larger than memory with streaming. Learn it when pandas becomes too slow or too memory-hungry, or when you want cleaner, SQL-like data pipelines in Python.

Before you start

Polars builds on these; the tree links to the exact lessons you need.

How deep do you want to go?

1. EssentialsRead and write simple code, do the everyday basics7 lessons · 1 hour in total
2. PracticalUse it productively at work, with the usual idioms13 lessons · 3 hours in total
3. AdvancedThe less common features, performance and trade-offs17 lessons · 4 hours in total
4. ExpertInternals and the edge cases experts know20 lessons · 4 hours in total

The Polars tree

PolarsDataFrame, Series and schemaDataFrame, Seriesand schemaExpressions and contextsExpressions andcontextsReading and writing CSV and ParquetReading and writingCSV and ParquetFiltering, sorting and selecting rowsFiltering, sorting andselecting rowsConditional columns with when/thenConditional columnswith when/thenGroup by and aggregateGroup by andaggregateMissing data: null and NaNMissing data: nulland NaNThe lazy API: scan and collectThe lazy API: scanand collectJoins and concatenationJoins andconcatenationSelecting many columns: selectorsSelecting manycolumns: selectorsStrings, dates and castingStrings, dates andcastingWindow functions with over()Window functionswith over()Reshaping: pivot and unpivotReshaping: pivot andunpivotDictionariesDictionariesModules and importsModules and importsDefining functionsDefining functionsReading and writing filesReading and writingfiles
Essentials and Practical shown (13 of 20 lessons); the full list is below. Click a lesson to read it.

All 20 lessons, in order

DataFrames and expressions

  1. DataFrame, Series and schema · Essentials · 10 min

    Create a Polars DataFrame, read its schema, and look at the data with head, describe and glimpse.

  2. Expressions and contexts · Essentials · 15 min

    Describe column computations with pl.col expressions and run them in select, with_columns and filter.

  3. Selecting many columns: selectors · Practical · 12 min

    Apply one expression to many columns with pl.all, pl.col lists, dtype selection and polars.selectors.

Reading and writing data

  1. Reading and writing CSV and Parquet · Essentials · 12 min

    Load files with read_csv and read_parquet, fix types on the way in, and save results as Parquet.

Transforming data

  1. Filtering, sorting and selecting rows · Essentials · 10 min

    Keep rows with filter, combine conditions with & and |, and order rows with sort, head and top_k.

  2. Conditional columns with when/then · Essentials · 8 min

    Build if/else column logic with pl.when().then().otherwise(), chaining several branches.

  3. Group by and aggregate · Essentials · 15 min

    Summarize data per group with group_by().agg(), using several aggregation expressions at once.

  4. Missing data: null and NaN · Essentials · 10 min

    Understand null versus NaN in Polars and handle gaps with is_null, fill_null, drop_nulls and coalesce.

  5. Joins and concatenation · Practical · 15 min

    Combine tables with join (inner, left, full, semi, anti) and stack them with pl.concat.

  6. Window functions with over() · Practical · 12 min

    Compute per-group values without collapsing rows using .over(), including ranks, shares and running totals.

  7. Reshaping: pivot and unpivot · Practical · 10 min

    Turn long data wide with pivot and wide data long with unpivot, and know which shape each task wants.

  8. Time series: dynamic groups, rolling and asof · Advanced · 15 min

    Resample with group_by_dynamic, compute time-based rolling windows, and match events with join_asof.

Lazy queries

  1. The lazy API: scan and collect · Practical · 15 min

    Build a LazyFrame with scan_* or .lazy(), chain operations into a query plan, and run it with collect().

  2. Query plans and optimizations · Advanced · 15 min

    Read a lazy query plan with explain(), and see predicate pushdown, projection pushdown and common-subplan elimination at work.

  3. Running SQL on DataFrames · Advanced · 10 min

    Query DataFrames and LazyFrames with SQL through pl.sql, SQLContext and LazyFrame.sql.

Strings, dates and nested types

  1. Strings, dates and casting · Practical · 15 min

    Use the str and dt namespaces, parse text into dates with str.to_date, and convert types with cast.

  2. Lists, arrays and structs · Advanced · 15 min

    Work with List, Array and Struct columns: list namespace, explode, implode, unnest and struct fields.

Performance and internals

  1. Streaming and larger-than-memory data · Expert · 15 min

    Process data bigger than RAM with the streaming engine, sink_* outputs, batches and hive-partitioned datasets.

  2. Python UDFs vs native code and plugins · Expert · 15 min

    Know the cost of map_elements and map_batches, how to stay native, and when to write a Rust expression plugin.

  3. Arrow memory, chunks and interop · Expert · 15 min

    Understand Polars' Arrow-based columns, chunking and rechunk, string views, categoricals, and zero-copy exchange with pandas, NumPy and PyArrow.