Skip to content
masterclassBuddyTech Buzz5 fresh blogs · 5:00 AM IST

Polars · Module

df.unpivot

Reshapes a DataFrame from wide to long form, retaining optional identifier columns. Selected measured columns become rows represented by variable and value fields.

Since
1.0.0

How it works

The method reshapes selected measured columns into two columns: one containing each source column name and one containing its corresponding value. Identifier columns remain attached to every generated row; when on is omitted, every column not listed in index is measured.

Syntax

DataFrame.unpivot(on: ColumnNameOrSelector | Sequence[ColumnNameOrSelector] | None = None, *, index: ColumnNameOrSelector | Sequence[ColumnNameOrSelector] | None = None, variable_name: str | None = None, value_name: str | None = None) -> DataFrame

Parameters

NameTypeDescription
onColumnNameOrSelector | Sequence[ColumnNameOrSelector] | NoneColumns or selectors to use as value variables; if None, all columns not in index are used.
indexColumnNameOrSelector | Sequence[ColumnNameOrSelector] | NoneColumns or selectors to use as identifier variables.
variable_namestr | NoneName for the generated variable column; defaults to "variable".
value_namestr | NoneName for the generated value column; defaults to "value".

Returns

DataFrame

Key points

  • Use this method to transform columns representing separate measurements into rows.
  • Columns supplied through index are retained as identifier fields in the reshaped result.
  • When on is None, columns outside index become the measured variables and are moved into rows.
  • The reshaped measurements are represented by a column-name field and a value field.
  • Use variable_name to replace the default name of the column containing source-column names.
  • Use value_name to replace the default name of the column containing measurement values.

Common mistakes

  • Do not rely on the order of rows in the result; sort explicitly when deterministic output is required.

Example: Convert wide measurements to long form

import polars as pl

frame = pl.DataFrame({
    "city": ["Oslo", "Rome"],
    "jan": [4, 12],
    "feb": [5, 14],
})

long = frame.unpivot(
    on=["jan", "feb"],
    index="city",
    variable_name="month",
    value_name="temperature",
)
print(long)

Converts the monthly measurement columns into rows while retaining the city identifier.

When to use it

Tidy wide tables

Normalize repeated measurement columns for analysis or visualization.

Selector-driven reshaping

Convert a selected group of typed columns into a name-value representation.

Long-form pipelines

Prepare a wide report for joins or grouped aggregation by measurement type.

Interview questions

QWhat does DataFrame.unpivot do?

unpivot changes a DataFrame from wide format to long format. The columns selected by on become values represented along the row axis, while index columns remain identifiers.

Follow-up: What happens when on is omitted? Every column not included in index is selected as a measured column.

QExplain the purpose of each main parameter.

on identifies the measured columns and index identifies the columns to preserve as identifiers. variable_name and value_name customize the two generated non-identifier columns, whose defaults are variable and value.

Follow-up: How would you reshape only numeric measurements while preserving a label? Pass a numeric selector for on and the label column as index.

QWhat does the result contain, and is its ordering guaranteed?

The method returns a DataFrame with the identifier columns plus the variable and value columns. If on is an empty selection, no columns are used as measured variables.

Follow-up: How can the output be made predictable for downstream comparisons? Sort it after unpivoting, because row order is unspecified.

  • polars.DataFrame.pivot
  • polars.selectors.numeric
  • pandas.DataFrame.melt

Source: polars.DataFrame.unpivot. Checked 2026-10-15.