Reshaping
Pivot Table (Long to Wide)
Fold long-form rows (row_key, col_key, value) into a nested dict-of-dicts,
filling each cell from the matching triple. With pandas, pivot_table does
this in one call and handles duplicate cells via an aggregation function.
By hand
Scan parallel lists rows, cols, vals in lock-step. For each triple,
create the inner dict for a new row key when it first appears, then store the
value at grid[r][c]. The grid grows key-by-key as we process each triple.
naive.py
Replay: real traced execution (multi-file project)
rows = ['a', 'a', 'b', 'b', 'c', 'c']
cols = ['x', 'y', 'x', 'y', 'x', 'y']
vals = [1, 2, 3, 4, 5, 6]
grid = {}
for i in range(len(rows)):
r = rows[i]
c = cols[i]
v = vals[i]
if r not in grid:
grid[r] = {}
grid[r][c] = v
print('RESULT:', grid)
rows ← ['a', 'a', 'b', 'b', 'c', 'c']
1rows = ['a', 'a', 'b', 'b', 'c', 'c']2cols = ['x', 'y', 'x', 'y', 'x', 'y']values this step['a', 'a', 'b', 'b', 'c', 'c']rowscols ← ['x', 'y', 'x', 'y', 'x', 'y']
1rows = ['a', 'a', 'b', 'b', 'c', 'c']2cols = ['x', 'y', 'x', 'y', 'x', 'y']3vals = [1, 2, 3, 4, 5, 6]values this step['x', 'y', 'x', 'y', 'x', 'y']colsvals ← [1, 2, 3, 4, 5, 6]
2cols = ['x', 'y', 'x', 'y', 'x', 'y']3vals = [1, 2, 3, 4, 5, 6]4grid = {}values this step[1, 2, 3, 4, 5, 6]valsgrid ← {}
3vals = [1, 2, 3, 4, 5, 6]4grid = {}5for i in range(len(rows)):values this step{}gridi ← 0
4grid = {}5for i in range(len(rows)):6 r = rows[i]values this step0ir ← 'a'
5for i in range(len(rows)):6 r = rows[i]7 c = cols[i]values this step'a'rc ← 'x'
6r = rows[i]7c = cols[i]8v = vals[i]values this step'x'cv ← 1
7c = cols[i]8v = vals[i]9if r not in grid:values this step1vif r not in grid:
8v = vals[i]9if r not in grid:10 grid[r] = {}grid ← {'a': {}}
9if r not in grid:10 grid[r] = {}11grid[r][c] = vvalues this step{} → {'a': {}}gridgrid ← {'a': {'x': 1}}
10 grid[r] = {}11 grid[r][c] = v12print('RESULT:', grid)values this step{'a': {}} → {'a': {'x': 1}}gridi ← 1
4grid = {}5for i in range(len(rows)):6 r = rows[i]values this step0 → 1ir = rows[i]
5for i in range(len(rows)):6 r = rows[i]7 c = cols[i]c ← 'y'
6r = rows[i]7c = cols[i]8v = vals[i]values this step'x' → 'y'cv ← 2
7c = cols[i]8v = vals[i]9if r not in grid:values this step1 → 2vif r not in grid:
8v = vals[i]9if r not in grid:10 grid[r] = {}grid ← {'a': {'x': 1, 'y': 2}}
10 grid[r] = {}11 grid[r][c] = v12print('RESULT:', grid)values this step{'a': {'x': 1}} → {'a': {'x': 1, 'y': 2}}gridi ← 2
4grid = {}5for i in range(len(rows)):6 r = rows[i]values this step1 → 2ir ← 'b'
5for i in range(len(rows)):6 r = rows[i]7 c = cols[i]values this step'a' → 'b'rc ← 'x'
6r = rows[i]7c = cols[i]8v = vals[i]values this step'y' → 'x'cv ← 3
7c = cols[i]8v = vals[i]9if r not in grid:values this step2 → 3vif r not in grid:
8v = vals[i]9if r not in grid:10 grid[r] = {}grid ← {'a': {'x': 1, 'y': 2}, 'b': {}}
9if r not in grid:10 grid[r] = {}11grid[r][c] = vvalues this step{'a': {'x': 1, 'y': 2}} → {'a': {'x': 1, 'y': 2}, 'b': {}}gridgrid ← {'a': {'x': 1, 'y': 2}, 'b': {'x': 3}}
10 grid[r] = {}11 grid[r][c] = v12print('RESULT:', grid)values this step{'a': {'x': 1, 'y': 2}, 'b': {}} → {'a': {'x': 1, 'y': 2}, 'b': {'x': 3}}gridi ← 3
4grid = {}5for i in range(len(rows)):6 r = rows[i]values this step2 → 3ir = rows[i]
5for i in range(len(rows)):6 r = rows[i]7 c = cols[i]c ← 'y'
6r = rows[i]7c = cols[i]8v = vals[i]values this step'x' → 'y'cv ← 4
7c = cols[i]8v = vals[i]9if r not in grid:values this step3 → 4vif r not in grid:
8v = vals[i]9if r not in grid:10 grid[r] = {}grid ← {'a': {'x': 1, 'y': 2}, 'b': {'x': 3, 'y': 4}}
10 grid[r] = {}11 grid[r][c] = v12print('RESULT:', grid)values this step{'a': {'x': 1, 'y': 2}, 'b': {'x': 3}} → {'a': {'x': 1, 'y': 2}, 'b': {'x': 3, 'y': 4}}gridi ← 4
4grid = {}5for i in range(len(rows)):6 r = rows[i]values this step3 → 4ir ← 'c'
5for i in range(len(rows)):6 r = rows[i]7 c = cols[i]values this step'b' → 'c'rc ← 'x'
6r = rows[i]7c = cols[i]8v = vals[i]values this step'y' → 'x'cv ← 5
7c = cols[i]8v = vals[i]9if r not in grid:values this step4 → 5vif r not in grid:
8v = vals[i]9if r not in grid:10 grid[r] = {}grid ← {'a': {'x': 1, 'y': 2}, 'b': {'x': 3, 'y': 4}, 'c': {}}
9if r not in grid:10 grid[r] = {}11grid[r][c] = vvalues this step{'a': {'x': 1, 'y': 2}, 'b': {'x': 3, 'y': 4}} → {'a': {'x': 1, 'y': 2}, 'b': {'x': 3, 'y': 4}, 'c': {}}gridgrid ← {'a': {'x': 1, 'y': 2}, 'b': {'x': 3, 'y': 4}, 'c': {'x': 5}}
10 grid[r] = {}11 grid[r][c] = v12print('RESULT:', grid)values this step{'a': {'x': 1, 'y': 2}, 'b': {'x': 3, 'y': 4}, 'c': {}} → {'a': {'x': 1, 'y': 2}, 'b': {'x': 3, 'y': 4}, 'c': {'x': 5}}gridi ← 5
4grid = {}5for i in range(len(rows)):6 r = rows[i]values this step4 → 5ir = rows[i]
5for i in range(len(rows)):6 r = rows[i]7 c = cols[i]c ← 'y'
6r = rows[i]7c = cols[i]8v = vals[i]values this step'x' → 'y'cv ← 6
7c = cols[i]8v = vals[i]9if r not in grid:values this step5 → 6vif r not in grid:
8v = vals[i]9if r not in grid:10 grid[r] = {}grid ← {'a': {'x': 1, 'y': 2}, 'b': {'x': 3, 'y': 4}, 'c': {'x': 5, 'y': 6}}
10 grid[r] = {}11 grid[r][c] = v12print('RESULT:', grid)values this step{'a': {'x': 1, 'y': 2}, 'b': {'x': 3, 'y': 4}, 'c': {'x': 5}} → {'a': {'x': 1, 'y': 2}, 'b': {'x': 3, 'y': 4}, 'c': {'x': 5, 'y': 6}}gridfor i in range(len(rows)):
4grid = {}5for i in range(len(rows)):6 r = rows[i]stdout ← RESULT: {'a': {'x': 1, 'y': 2}, 'b': {'x': 3, 'y': 4}, 'c': {'x': 5, 'y': 6}}
11 grid[r][c] = v12print('RESULT:', grid)values this stepRESULT: {'a': {'x': 1, 'y': 2}, 'b': {'x': 3, 'y': 4}, 'c': {'x': 5, 'y': 6}}stdout
With pandas
df.pivot_table(index='r', columns='c', values='v') reshapes the long
DataFrame into a wide one. The snapshot shows the row index, the column
labels, and per-column value lists.
library.py
import pandas as pd
from dalib.display import set_display
set_display()
rows = ['a', 'a', 'b', 'b', 'c', 'c']
cols = ['x', 'y', 'x', 'y', 'x', 'y']
vals = [1, 2, 3, 4, 5, 6]
df = pd.DataFrame({'r': rows, 'c': cols, 'v': vals})
pt = df.pivot_table(index='r', columns='c', values='v')
result = {r: {c: int(pt.loc[r, c]) for c in pt.columns} for r in pt.index}
print('index:', pt.index.tolist())
print('columns:', pt.columns.tolist())
print('x:', [int(pt.loc[r, 'x']) for r in pt.index])
print('y:', [int(pt.loc[r, 'y']) for r in pt.index])
print('RESULT:', result)
index: ['a', 'b', 'c']
columns: ['x', 'y']
x: [1, 3, 5]
y: [2, 4, 6]
RESULT: {'a': {'x': 1, 'y': 2}, 'b': {'x': 3, 'y': 4}, 'c': {'x': 5, 'y': 6}}
Implementation notes
pivot_tabledefaults toaggfunc='mean'. With unique(index, columns)pairs (no duplicate cells), mean of a single value is that value — the result matches the original. Passaggfunc='sum'oraggfunc='count'to aggregate duplicate cells instead.- Cells with no matching row in the long data become
NaN. Supplyfill_value=0(or another sentinel) to replace them. - The result dtype is
float64by default (mean returns float). Cast withint()after confirming noNaNcells. - Cross-reference:
pivot-long-to-wide(python-data-basics) for the pure-Python nested-dict version;melt-wide-to-long(this chapter) for the inverse operation.