Skip to main content
v2026.11,858 entries · CC-BY 4.0
LAC HealthMedical & Research SuppliesReagents, PPE & instruments — chain-of-custody documented.Fast, traceable sourcing built for regulated research environments, from bench consumables to instrumentation.Shop lac.us CodeCASRAIlac.us

pandas melt: Syntax, Parameters and Wide-to-Long Examples

How pandas melt reshapes wide data to long: parameters, a repeated-measures example with real output, unmelt, errors, and melt vs pivot and stack.

Written and maintained by CASRAI Editorial Board

Last updated

pandas melt (pandas.melt() or its identical method DataFrame.melt()) reshapes a DataFrame from wide to long format: the columns you name as identifiers stay as they are, and every other column is unpivoted into two new columns, variable (the old column name) and value (the cell contents). This guide is for researchers and analysts who need to turn one-column-per-measurement data into one-row-per-observation data for grouping, plotting or modelling. It covers the signature, a worked research example with output run under pandas 3.0.5, the errors you are most likely to meet, and how melt compares with its neighbours and with the equivalent steps in Stata, SAS and Power Query.

What pandas melt is used for in research

Instruments, surveys and repeated-measures designs often produce wide tables: one row per participant, one column per time point or item. Most grouping, plotting and modelling tools expect long data instead, with one row per observation. The pandas user guide describes melt as reshaping so that one or more columns are identifier variables, while all other columns (the measured variables) are unpivoted to the row axis, leaving two non-identifier columns named variable and value by default. See also tidy data rules for structuring research data and data wrangling.

Install or access

melt ships with pandas; there is no separate package. The official installation page gives pip install pandas or, with conda, conda install -c conda-forge pandas. Then import pandas as pd. If you are new to building frames, see how to create a DataFrame in Python.

Syntax and parameters

From the pandas 3.1.1 API reference:

pandas.melt(frame, id_vars=None, value_vars=None, var_name=None,            value_name='value', col_level=None, ignore_index=True)

It returns the unpivoted DataFrame. DataFrame.melt takes the same arguments without frame.

Parameter What it does (per the pandas documentation)
id_vars Column(s) to use as identifier variables; these are kept as columns.
value_vars Column(s) to unpivot. If not specified, all columns that are not set as id_vars are used.
var_name Name for the variable column. If None, uses frame.columns.name or ‘variable’. Must be a scalar if the columns are a MultiIndex.
value_name Name for the value column, default ‘value’. It cannot be an existing column label.
col_level If the columns are a MultiIndex, the level to melt.
ignore_index Default True. If False, the original index is retained and index labels are repeated as necessary.

Step-by-step: wide repeated-measures scores to long format

Illustrative composite: the data below are invented for demonstration and do not come from any real study. Each participant has a score at three time points in separate columns.

  1. Build or load the wide table.
    import pandas as pdwide = pd.DataFrame({    "participant": ["P01", "P02", "P03"],    "group": ["control", "treatment", "treatment"],    "t1": [12, 14, 11], "t2": [13, 18, 15], "t3": [13, 21, 19]})
  2. Name the identifier columns in id_vars and the measurement columns in value_vars, and give the new columns meaningful names.
    long = wide.melt(id_vars=["participant", "group"],                 value_vars=["t1", "t2", "t3"],                 var_name="timepoint", value_name="score")
  3. Use the long table, for example to summarise by group and time point.
    long.groupby(["group", "timepoint"])["score"].mean()

Output and how to read it

Output of step 2 under pandas 3.0.5: three participants times three time points gives nine rows. Rows are ordered by melted column first (all t1 rows, then t2, then t3), and the original index is discarded and renumbered 0 to 8 because ignore_index defaults to True.

  participant      group timepoint  score0         P01    control        t1     121         P02  treatment        t1     142         P03  treatment        t1     113         P01    control        t2     134         P02  treatment        t2     185         P03  treatment        t2     156         P01    control        t3     137         P02  treatment        t3     218         P03  treatment        t3     19

Output of step 3 (group means):

group      timepointcontrol    t1           12.0           t2           13.0           t3           13.0treatment  t1           12.5           t2           16.5           t3           20.0

Melt multiple columns, or all the rest

List several names in value_vars to unpivot only those. Omit value_vars and every column not in id_vars is unpivoted, which is the shortest form when all remaining columns are measurements.

Keep the original index

The user guide notes that melt ignores the index. With ignore_index=False the original index values are kept but duplicated: in the example above the index would run 0, 1, 2, 0, 1, 2, 0, 1, 2. A repeated index is a sign you may want participant as an explicit identifier column instead.

MultiIndex columns

Use col_level to melt one level. The API reference also shows passing tuples, as in pd.melt(df, id_vars=[("A", "D")], value_vars=[("B", "E")]), which produces columns named (A, D), variable_0, variable_1 and value. A custom var_name must be a scalar when the columns are a MultiIndex.

Opposite of melt: back to wide (unmelt)

The documentation does not describe pivot as melt’s inverse; as an editorial interpretation, for data with a unique identifier-and-variable combination, pivot restores the wide shape:

back = long.pivot(index=["participant", "group"],                  columns="timepoint", values="score").reset_index()

This returned the original three rows with columns participant, group, t1, t2, t3 in the test run. The user guide states that pivot() can only handle unique rows specified by index and columns, and to use pivot_table() if the data contains duplicates.

melt vs wide_to_long, stack, pivot and explode

Function Use it when Source wording
melt You name identifier columns and unpivot the rest into variable/value. User guide: identifier variables stay, measured variables go to the row axis.
wide_to_long Column names share a stub plus a suffix (A1970, B1980) and you want the suffix as its own level. User guide: “similar to melt() with more customization for column matching.”
stack / unstack You want to move a column level into the row index, or back, on an indexed frame. User guide: pivot a level of column labels or of the row index; unstack can create missing values and fill_value overrides them.
pivot Long to wide where each index/columns pair is unique. User guide: only handles unique rows.
pivot_table Long to wide where duplicates exist and must be aggregated. Listed under melt’s See also and recommended for duplicate data.
explode Cells hold lists that should become rows. Listed under melt’s See also.

Troubleshooting

Messages below were produced in a local run under pandas 3.0.5.

  • ValueError: value_name (group) cannot match an element in the DataFrame columns. You passed a value_name that is already a column label. Choose a new name.
  • KeyError: The following id_vars or value_vars are not present in the DataFrame: [‘t9’] A name in id_vars or value_vars does not match a column label exactly; check spelling and case.
  • ValueError: Index contains duplicate entries, cannot reshape raised by pivot when going back to wide with repeated index/column pairs. Use pivot_table with an aggfunc such as “mean”, which in the test returned 1.5 for two values of 1 and 2, or fix the duplicates first.
  • Unexpected row order or index. Rows are stacked column by column, and the index is renumbered unless ignore_index=False.

Free alternatives in other tools

Tool Equivalent task CASRAI guide
Stata Reshape wide to long reshape command in Stata
SAS Transposing variables to observations PROC TRANSPOSE in SAS
Power Query (Excel, Power BI) Unpivot columns how to use Power Query

Within Python, melt is the built-in route and needs no extra package. To combine frames before or after reshaping, see pandas concat.

FAQ

What does pandas melt do?

It converts a wide DataFrame to long format, keeping the id_vars columns and turning the other columns into variable and value columns.

Is df.melt() different from pd.melt()?

No. The API reference lists DataFrame.melt as the identical method.

How do I melt multiple columns?

Pass them as a list to value_vars, or omit value_vars to melt every column not in id_vars.

Is there a pandas unpivot function?

Unpivoting is what melt does; the user guide describes unpivoting measured variables to the row axis.

What is the opposite of pandas melt?

Use pivot for unique keys or pivot_table to aggregate duplicates; see the table above.

Sources

Follow CASRAI

Research-administration guidance, standards updates and independent tool reviews.

Ask CASRAI · free to try

Ask about pandas melt: Syntax, Parameters and Wide-to-Long Examples

Ask your first 2 questions free below. Subscribers get 150 a day for $29 a month.

An AI assistant specialized in research administration. It cites the sources behind every answer, labels web answers and says when it can't answer.

Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.

Works on this site and inside Claude, Cursor and the AI tools you already use.

Everything CASRAI publishes — this page, the dictionary, the guides and the news — stays free to read, with no account and no card.

Referenced across the research world

University of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logoUniversity of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logo
  • University of Cambridge logo
  • Columbia University logo
  • Crossref logo
  • University of Edinburgh logo
  • Harvard University logo
  • University of Oxford logo
  • Princeton University logo
  • Stanford School of Medicine logo
  • University College London logo
  • ORCID logo

View CASRAI adoption →