Learn how to reshape DataFrames in GPandas with Stack (wide → long) and Unstack (long → wide), and how to build a composite row index with SetMultiIndex. These complement the Pivot and Melt operations.

 

Overview

OperationMethodDescription
Wide → longStack()Turn every cell into a row
Long → wideUnstack()Inverse of Stack
Composite indexSetMultiIndex()Join columns into a single index label

All methods return a new DataFrame.

 


 

Sample Data

The Stack/Unstack examples use this DataFrame with a custom index:

(index)MathScience
Alice9085
Bob8075

 

Setup Code

package main

import (
    "fmt"
    "log"

    "github.com/apoplexi24/gpandas"
)

func main() {
    gp := gpandas.GoPandas{}

    df, _ := gp.DataFrame(
        []string{"Math", "Science"},
        []gpandas.Column{
            {90.0, 80.0},
            {85.0, 75.0},
        },
        map[string]any{"Math": gpandas.FloatCol{}, "Science": gpandas.FloatCol{}},
    )
    _ = df.SetIndex([]string{"Alice", "Bob"})

    // Examples follow...
}

 


 

Stack

Reshapes from wide to long format, producing three columns: index (the original row label), variable (the former column name), and value (the cell value). Each non-null cell becomes one row; null cells are dropped.

 

Function Signature

func (df *DataFrame) Stack() (*DataFrame, error)

 

Example

long, err := df.Stack()
if err != nil {
    log.Fatalf("Stack failed: %v", err)
}
fmt.Println(long.String())
+-------+----------+-------+
| index | variable | value |
+-------+----------+-------+
| Alice | Math     | 90    |
| Alice | Science  | 85    |
| Bob   | Math     | 80    |
| Bob   | Science  | 75    |
+-------+----------+-------+
[4 rows x 3 columns]

 

Stack / Unstack Round Trip

flowchart LR
    subgraph Wide["Wide"]
        W["Alice: Math 90, Science 85<br/>Bob: Math 80, Science 75"]
    end

    subgraph Long["Long (index/variable/value)"]
        L["Alice/Math/90<br/>Alice/Science/85<br/>Bob/Math/80<br/>Bob/Science/75"]
    end

    W -->|Stack| L
    L -->|Unstack| W

    style Wide fill:#1e293b,stroke:#3b82f6,stroke-width:2px
    style Long fill:#1e293b,stroke:#22c55e,stroke-width:2px

 


 

Unstack

Reshapes a long-format DataFrame (as produced by Stack) back to wide format. It expects columns named index, variable, and value: index values become row labels, distinct variable values become columns (sorted), and value fills the cells. Missing combinations are null.

 

Function Signature

func (df *DataFrame) Unstack() (*DataFrame, error)

 

Example

wide, err := long.Unstack()
if err != nil {
    log.Fatalf("Unstack failed: %v", err)
}
fmt.Println(wide.String())
+------+---------+
| Math | Science |
+------+---------+
| 90   | 85      |
| 80   | 75      |
+------+---------+
[2 rows x 2 columns]

The row labels (Alice, Bob) are restored as the DataFrame index.

 


 

SetMultiIndex

Builds a composite index by joining the values of several columns with a separator (default _).

Note: Unlike pandas’ true hierarchical MultiIndex, GPandas represents the composite index as a single joined string label per row. The source columns are kept in the DataFrame, so the operation is non-destructive.

 

Function Signature

func (df *DataFrame) SetMultiIndex(columns []string, sep ...string) (*DataFrame, error)

 

Example

mi, _ := gp.DataFrame(
    []string{"Country", "City", "Pop"},
    []gpandas.Column{
        {"USA", "USA", "UK"},
        {"NYC", "LA", "London"},
        {int64(8), int64(4), int64(9)},
    },
    map[string]any{"Country": gpandas.StringCol{}, "City": gpandas.StringCol{}, "Pop": gpandas.IntCol{}},
)

indexed, err := mi.SetMultiIndex([]string{"Country", "City"})
if err != nil {
    log.Fatalf("SetMultiIndex failed: %v", err)
}
fmt.Printf("Index = %v\n", indexed.Index)
Index = [USA_NYC USA_LA UK_London]

The composite labels become the row index, while the Country, City, and Pop columns remain available in the DataFrame.

 


 

Error Handling

Common Errors

ErrorCauseSolution
“DataFrame is nil”Operating on nil DataFrameCheck DataFrame initialization
“required column ‘X’ not found”Unstack input missing index/variable/valueUse the output of Stack
“column ‘X’ not found”SetMultiIndex on a missing columnVerify the columns exist
“at least one column is required”Empty SetMultiIndex columnsProvide at least one column

 


 

Thread Safety

Reshaping operations read under a read lock and return new DataFrames, leaving the original unchanged.

 


 

See Also