DataFrame, Series and schema

Polars · Essentials · 10 min

Everything in Polars starts with a DataFrame of typed, named columns, so you need to read its shape and schema fluently.

A Polars DataFrame is a table of named columns, and each column is a Series: a typed, one-dimensional array stored in the Apache Arrow format. Every column has exactly one data type, such as Int64, Float64, String, Boolean or Date. The mapping of names to types is the schema.

The quickest way to build one is from a dict of lists: pl.DataFrame({"name": [...], "age": [...]}). Polars infers the types, or you can pass schema={"age": pl.Int32} to choose them.

Things to know straight away:

  • df.shape, df.height, df.width give the size; df.columns the names; df.schema the names with types.
  • df.head(n), df.tail(n) and df.sample(n) show rows; df.glimpse() shows one line per column, handy for wide tables.
  • df.describe() gives count, null count, mean, min, max and quantiles.
  • df["age"] returns a Series; df.to_dicts() and df.rows() give plain Python data.

Unlike pandas there is no index. Rows are identified by position or by the values in your columns, which makes joins and group-bys explicit and removes a whole class of alignment surprises. Polars also never mutates a frame in place: methods return a new DataFrame, and the underlying column buffers are shared rather than copied, so this is cheap.

Import it as import polars as pl, the universal convention.

Example

import polars as pl

df = pl.DataFrame(
    {
        "name": ["Ana", "Ben", "Cy"],
        "age": [34, 28, None],
        "city": ["Oslo", "Lima", "Oslo"],
    },
    schema_overrides={"age": pl.Int32},
)
print(df.shape)                 # (3, 3)
print(df.schema)
# Schema({'name': String, 'age': Int32, 'city': String})
print(df["age"].null_count())   # 1
print(df.head(2).rows())        # [('Ana', 34, 'Oslo'), ('Ben', 28, 'Lima')]
print(df.to_dicts()[2])         # {'name': 'Cy', 'age': None, 'city': 'Oslo'}

Remember

  • A DataFrame is a set of named, typed Series sharing one length
  • Check df.schema early: types drive everything else
  • There is no index; rows are found by their values

Watch out for

  • Expecting df.loc / index alignment from pandas: Polars has neither.

Check yourself

  1. What does a Polars DataFrame have that a pandas DataFrame also has, and what does it lack?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.pola.rs/user-guide/concepts/data-types-and-structures/