Pandas MultiIndex
MultiIndex is a powerful indexing feature in Pandas that allows creating multi-level hierarchical structures on rows or columns. This is especially useful when dealing with high-dimensional data, group statistics, and panel data.
Creating MultiIndex
Creating from a List
Example
# Method 1: Creating using arrays
arrays = [
["A", "A", "B", "B", "C", "C"],
[1, 2, 1, 2, 1, 2]
]
# Using pd.MultiIndex.from_arrays
index = pd.MultiIndex.from_arrays(arrays, names=["Category", "Number"])
print("Created from arrays:")
print(index)
print()
# Method 2: Using a list of tuples
tuples = [
("A", 1), ("A", 2), ("B", 1), ("B", 2), ("C", 1), ("C", 2)
]
index = pd.MultiIndex.from_tuples(tuples, names=["Category", "Number"])
print("Created from tuples:")
print(index)
print()
# Method 3: Using product
index = pd.MultiIndex.from_product(
[["A", "B", "C"], [1, 2, 3]],
names=["Category", "Number"]
)
print("Created from product:")
print(index)
Creating a DataFrame with MultiIndex
Example
import numpy as np
# Creating a DataFrame with MultiIndex
df = pd.DataFrame(
np.random.randn(6, 4),
index=pd.MultiIndex.from_tuples(
[("2024", "Q1"), ("2024", "Q2"), ("2024", "Q3"),
("2025", "Q1"), ("2025", "Q2"), ("2025", "Q3")]
),
columns=["Beijing", "Shanghai", "Guangzhou", "Shenzhen"]
)
df.index.names = ["Year", "Quarter"]
print("DataFrame with MultiIndex:")
print(df)
Accessing MultiIndex
Accessing using loc/iloc
Example
# Creating sample data
df = pd.DataFrame({
"Chinese": [85, 92, 78, 88],
"Math": [90, 88, 95, 82]
}, index=pd.MultiIndex.from_tuples(
[("Grade 10", "Class A"), ("Grade 10", "Class B"), ("Grade 11", "Class A"), ("Grade 11", "Class B")],
names=["Grade", "Class"]
))
print("Original data:")
print(df)
print()
# Accessing outer index
print("Accessing all Grade 10:")
print(df.loc["Grade 10"])
print()
# Accessing inner index
print("Accessing Class A:")
print(df.loc[:, "Class A"])
print()
# Accessing multiple index levels
print("Accessing Class A of Grade 10:")
print(df.loc[("Grade 10", "Class A")])
Accessing using xs
Example
# Creating sample data
df = pd.DataFrame({
"Chinese": [85, 92, 78, 88],
"Math": [90, 88, 95, 82]
}, index=pd.MultiIndex.from_tuples(
[("Grade 10", "Class A"), ("Grade 10", "Class B"), ("Grade 11", "Class A"), ("Grade 11", "Class B")],
names=["Grade", "Class"]
))
# Using xs to access values at a specific level
print("Accessing Grade 10 using xs:")
print(df.xs("Grade 10", level="Grade"))
print()
print("Accessing Class A using xs:")
print(df.xs("Class A", level="Class"))
Converting MultiIndex
Stacking and Unstacking
Example
import numpy as np
# Creating a wide-format DataFrame
df = pd.DataFrame(
np.arange(12).reshape(3, 4),
index=pd.MultiIndex.from_tuples(
[("Beijing", "2024"), ("Shanghai", "2024"), ("Guangzhou", "2024")]
),
columns=pd.MultiIndex.from_tuples(
[("Q1", "Revenue"), ("Q1", "Profit"), ("Q2", "Revenue"), ("Q2", "Profit")]
)
)
print("Original data (nested columns):")
print(df)
print()
# unstack: Convert inner index to columns
df_unstacked = df.unstack()
print("After unstack:")
print(df_unstacked)
print()
# stack: Convert columns to inner index
df_stacked = df_unstacked.stack()
print("After stack:")
print(df_stacked)
Sorting MultiIndex
Example
# Creating a DataFrame with unsorted index
df = pd.DataFrame({
"Value": [1, 2, 3, 4, 5, 6]
}, index=pd.MultiIndex.from_tuples(
[("C", 2), ("A", 1), ("B", 2), ("A", 2), ("C", 1), ("B", 1)],
names=["Letter", "Number"]
))
print("Unsorted data:")
print(df)
print()
# Sort by outer level
df_sorted1 = df.sort_index()
print("After sorting by outer level:")
print(df_sorted1)
print()
# Sort by inner level
df_sorted2 = df.sort_index(level=1)
print("After sorting by inner level:")
print(df_sorted2)
print()
# Sort by multiple levels
df_sorted3 = df.sort_index(level=[0, 1])
print("After sorting by multiple levels:")
print(df_sorted3)
Practical: Group Statistics
MultiIndex is very suitable for group statistics and pivot analysis.
Example
import numpy as np
# Creating sales data
np.random.seed(42)
df = pd.DataFrame({
"Year": ["2023"] * 6 + ["2024"] * 6,
"Quarter": ["Q1", "Q2", "Q3", "Q4"] * 3,
"Product": ["Phone", "Phone", "Computer", "Computer"] * 3,
"Region": ["East China", "South China", "North China"] * 4,
"Sales Amount": np.random.randint(100, 500, 12)
})
print("Original sales data:")
print(df)
print()
# Setting MultiIndex and performing group statistics
df_grouped = df.set_index(["Year", "Quarter", "Product", "Region"])
print("Grouped by year, quarter, product, region:")
print(df_grouped)
# Summarize by year
yearly = df_grouped.groupby(level="Year").sum()
print("\n"Annual sales:")
print(yearly)
# Summarize by year and quarter
quarterly = df_grouped.groupby(level=["Year", "Quarter"]).sum()
print("\n"Quarterly sales:")
print(quarterly)
Common Issues and Notes
1. Index level confusion
Be careful when operating on data to avoid mixing up levels. It is recommended to check before and after operations.df.index.names。
2. Index access errors
locUse label-based access,ilocUse position-based access; do not mix the two.
3. Duplicate index when using concat
When usingconcatto merge data, duplicate indexes may lead to unexpected results. You can useignore_index=Trueto reset.
Other ExtensionsMultiIndex is a core feature of Pandas for handling high-dimensional data. Using MultiIndex properly can make data organization cleaner and statistics more convenient.