Python Central HubSign in

Data Analytics with Python / Phase 3: Data Manipulation with Pandas

Reindexing and Data Alignment

Rearrange data onto a new index with reindex, understand automatic label alignment in arithmetic, and fill gaps with fill_value.

  • Reindexing — you explicitly ask pandas to rearrange an object onto a new index, introducing NaN for any label that wasn't already there.
  • Alignment — pandas does this automatically whenever you do arithmetic between two Series or DataFrames with different indexes.

Both boil down to the same rule: match by label, not by position.

reindex: rearranging onto a new index

Python
import pandas as pd
 
obj = pd.Series([4.5, 7.2, -5.3, 3.6], index=["d", "b", "a", "c"])
print(obj.reindex(["a", "b", "c", "d", "e"]))  # "e" wasn't there -> NaN

For ordered data, method="ffill" fills in the gaps using the last known value instead of leaving NaN:

Python
import numpy as np
 
obj3 = pd.Series(["blue", "purple", "yellow"], index=[0, 2, 4])
print(obj3.reindex(np.arange(6), method="ffill"))

Reindexing a DataFrame — rows, columns, or both

Python
frame = pd.DataFrame(
    np.arange(9).reshape((3, 3)),
    index=["a", "c", "d"],
    columns=["Ohio", "Texas", "California"],
)
 
print(frame.reindex(index=["a", "b", "c", "d"]))          # "b" is new -> NaN row
print(frame.reindex(columns=["Texas", "Utah", "California"]))  # "Utah" is new, "Ohio" dropped

Automatic alignment in arithmetic

You never call reindex yourself before adding two Series — pandas does it for you, using the union of both indexes:

Python
s1 = pd.Series([7.3, -2.5, 3.4, 1.5], index=["a", "c", "d", "e"])
s2 = pd.Series([-2.1, 3.6, -1.5, 4, 3.1], index=["a", "c", "e", "f", "g"])
 
print(s1 + s2)

Labels present in only one of the two Series become NaN in the result — "d" and "f"/"g" never had a matching partner to add against.

Filling gaps during arithmetic: fill_value

If you'd rather treat a missing label as 0 (or some other value) instead of NaN, use the method form of the operator with fill_value:

Python
df1 = pd.DataFrame(np.arange(9.0).reshape(3, 3), columns=list("bcd"))
df2 = pd.DataFrame(np.arange(12.0).reshape(4, 3), columns=list("bde"))
 
print(df1.add(df2, fill_value=0))

The same fill_value idea also works directly on reindex:

Python
print(df1.reindex(columns=df2.columns, fill_value=0))

Common pitfalls

  • df1 + df2 (the operator) always produces NaN for non-overlapping labels — use .add(), .sub(), .mul(), .div() with fill_value if you want zeros instead.
  • reindex creates missing rows/columns; it never drops data implicitly unless a label from the original index is missing from the new one.
  • method="ffill" on reindex requires the index to already be sorted in the order you expect the fill to follow.

Visualize it

diagram Two indexes aligning mermaid
Before an arithmetic operation, pandas takes the union of both indexes and reindexes each object onto it, introducing NaN for any label missing from one side.
sketch Aligning two mismatched indexes p5.js
Series 1 (amber) and Series 2 (blue) share some labels but not others; only the shared labels (green) produce a real result.

🧪 Try It Yourself

Exercise 1 – Reindex Onto a Larger Index

exerciseYour turn

Tab indents. Press Escape, then Tab, to leave the editor. Control plus Enter runs the code; Control plus Shift plus Enter submits it.

Output
Press Run to see what your code prints.

Exercise 2 – Automatic Alignment in Arithmetic

exerciseYour turn

Tab indents. Press Escape, then Tab, to leave the editor. Control plus Enter runs the code; Control plus Shift plus Enter submits it.

Output
Press Run to see what your code prints.

Exercise 3 – Fill Gaps Instead of Producing NaN

exerciseYour turn

Tab indents. Press Escape, then Tab, to leave the editor. Control plus Enter runs the code; Control plus Shift plus Enter submits it.

Output
Press Run to see what your code prints.

Check your understanding

quizCheck yourself
  1. What does obj.reindex(["a", "b", "c", "d", "e"]) give for the label e when obj has only a, b, c and d?

    Show answer

    A — NaN — Reindex introduces NaN for any label that was not in the original index unless you ask for a fill.

  2. For s1 with labels a, c, d, e and s2 with labels a, c, e, f, g, how many labels does s1 + s2 have and which are NaN?

    Show answer

    A — 6 labels, with d, f and g NaN — The result uses the union of the indexes. d, f and g appear in only one Series so they are NaN.

  3. How do you add two DataFrames and treat a missing label as 0 instead of NaN?

    Show answer

    A — df1.add(df2, fill_value=0) — The operator form always gives NaN for non-overlapping labels. The method form accepts fill_value.

  4. For obj3 with values blue, purple, yellow at index 0, 2, 4, what does obj3.reindex(np.arange(6), method="ffill") return at label 1?

    Show answer

    A — blue — ffill carries the last known value forward, so label 1 gets blue from label 0.

Next

With your index aligned the way you want, you're ready to narrow rows down further — continue to Filtering with Conditions (and, or, isin, query).

Was this page helpful?

Let us know how we did