You added a new column to your pandas DataFrame — the values look right, the logic looks sound — and Python threw ValueError: Length of values does not match length of index. Your DataFrame has 100 rows. Your new column has 50 values. Pandas will not guess which 50 rows to fill. Here is exactly why this happens and how to fix it for good.
In this guide, you will learn to:
- Understand exactly what causes
ValueError: Length of values does not match length of index - Reproduce it with clear, minimal examples
- Fix it using every applicable technique — from
reset_index()tomap() - Handle the trickiest variants: mismatched MultiIndex, groupby aggregates, and CSV loads
- Prevent this error from recurring in your data pipelines
Page Contents
What Does the Error Mean?
Every pandas DataFrame has an index — a row label that identifies each row. When you assign a new column with df['new_col'] = values, pandas checks that the number of values matches the number of rows (the length of the index). If they do not match, it raises ValueError: Length of values does not match length of index.
import pandas as pd
df = pd.DataFrame({"name": ["Alice", "Bob", "Charlie"], "age": [25, 30, 35]})
print(df)
# name age
# 0 Alice 25
# 1 Bob 30
# 2 Charlie 35
# This works: 3 values, 3 rows
df["score"] = [90, 85, 92]
# This raises ValueError: 2 values, 3 rows
df["grade"] = ["A", "B"]
# ValueError: Length of values (2) does not match length of index (3).
The error message tells you exactly what went wrong: pandas expected a sequence with the same length as the DataFrame’s index, but you provided a different number of elements. The fix depends entirely on why your values are the wrong length.
The Four Most Common Causes
Understanding why the length mismatch occurs is the key to fixing it permanently. Here are the four patterns that trigger this error most often.
Cause 1: Assigning a Shorter or Longer List to a Column
The textbook case. You have a DataFrame with N rows but assign M values where M ≠ N:
import pandas as pd
df = pd.DataFrame({"product": ["A", "B", "C", "D"], "price": [100, 200, 150, 80]})
# Oops — only 2 values for 4 rows
df["discount"] = [10, 20]
# ValueError: Length of values (2) does not match length of index (4).
The fix is straightforward: ensure the value sequence matches the index length, or use a technique that broadcasts correctly.
Cause 2: Mismatched Index After a Filter or Merge
After filtering rows, merging DataFrames, or joining on index, the left-hand side DataFrame may have a different number of rows than the Series or list you are trying to assign:
import pandas as pd
# Original DataFrame
df = pd.DataFrame({"name": ["Alice", "Bob", "Charlie", "Diana"],
"department": ["Eng", "Eng", "Sales", "Sales"]})
# Filter to only Eng employees (2 rows)
eng_df = df[df["department"] == "Eng"]
print(eng_df)
# name department
# 0 Alice Eng
# 1 Bob Eng
# This FAILS — eng_df has 2 rows, but salaries has 4 values
salaries = [90000, 85000, 75000, 70000]
eng_df["salary"] = salaries
# ValueError: Length of values (4) does not match length of index (2).
The root cause: you filtered the DataFrame to 2 rows, but your salary list still has 4 entries. Pandas cannot guess which 2 salaries belong to the 2 visible rows.
Cause 3: groupby().agg() Returns a Different Number of Rows Than the Original
When you aggregate a grouped DataFrame, the result has one row per group — not the same number of rows as the original. Trying to assign the result back without aligning the index causes the error:
import pandas as pd
df = pd.DataFrame({
"category": ["A", "A", "B", "B", "C"],
"value": [10, 20, 30, 40, 50]
})
# Group and aggregate — result has 3 rows (one per category)
grouped = df.groupby("category")["value"].sum()
print(grouped)
# category
# A 30
# B 70
# C 50
# Name: value, dtype: int64
# This FAILS — df has 5 rows, grouped has 3
df["category_sum"] = grouped
# ValueError: Length of values (3) does not match length of index (5).
Cause 4: Loading Data with a Mismatched Column Length from CSV
When reading a CSV with pd.read_csv(), if one column has fewer values than the header, pandas raises this error — but it also surfaces when you manually construct a DataFrame from raw parsed values where one column has fewer entries than the header:
import pandas as pd
# Manually constructing a DataFrame with mismatched column lengths
data = {
"name": ["Alice", "Bob", "Charlie"],
"age": [30, 25, 35],
"city": ["NYC", "LA"] # Oops — 2 values instead of 3
}
df = pd.DataFrame(data)
# ValueError: Length of values (2) does not match length of index (3).
How to Fix It: Five Techniques
Here are the five most reliable ways to fix this error, ordered from most recommended to situational.
Fix 1: Use reset_index() to Align After Filtering or Aggregation
If your values come from a filtered or aggregated DataFrame, reset_index(drop=True) converts the index back to a sequential range that matches the target DataFrame:
import pandas as pd
df = pd.DataFrame({
"name": ["Alice", "Bob", "Charlie", "Diana"],
"department": ["Eng", "Eng", "Sales", "Sales"]
})
# Filter to Eng — 2 rows
eng_df = df[df["department"] == "Eng"].copy()
# Reset to sequential index BEFORE assignment
eng_df = eng_df.reset_index(drop=True)
# Now lengths match (2 vs 2)
eng_df["employee_count"] = [1, 1]
print(eng_df)
# name department employee_count
# 0 Alice Eng 1
# 1 Bob Eng 1
Fix 2: Use map() to Pair Keys with Values
When you have a mapping (dict) between row identifiers and values, use map() on a key column to create a correctly-sized Series:
import pandas as pd
df = pd.DataFrame({"name": ["Alice", "Bob", "Charlie"],
"department": ["Eng", "Sales", "Eng"]})
# Salary mapping by department
salary_map = {"Eng": 90000, "Sales": 75000}
# map() always produces a Series with length == len(df)
df["salary"] = df["department"].map(salary_map)
print(df)
# name department salary
# 0 Alice Eng 90000
# 1 Bob Sales 75000
# 2 Charlie Eng 90000
Fix 3: Broadcast Scalars to All Rows Automatically
A single scalar value broadcasts to all rows automatically. If all rows should get the same value, just assign the scalar:
import pandas as pd
df = pd.DataFrame({"product": ["A", "B", "C", "D"], "price": [100, 200, 150, 80]})
# Correct: scalar broadcasts to all 4 rows
df["tax_rate"] = 0.18
print(df)
# product price tax_rate
# 0 A 100 0.18
# 1 B 200 0.18
# 2 C 150 0.18
# 3 D 80 0.18
# Wrong: list of 1 element for 4 rows
# df["discount"] = [5] # ValueError — needs 4 elements
Fix 4: Use reindex() to Align Mismatched Series
When you have a Series with a different index than your DataFrame, use reindex() to align them before assignment:
import pandas as pd
import numpy as np
df = pd.DataFrame({"name": ["Alice", "Bob", "Charlie", "Diana"],
"score": [90, 85, 72, 88]})
# Series with a mismatched index
new_scores = pd.Series([95, 80], index=[0, 2]) # Only Alice and Charlie
# reindex fills missing rows with NaN
df["adjusted_score"] = new_scores.reindex(df.index)
print(df)
# name score adjusted_score
# 0 Alice 90 95.0
# 1 Bob 85 NaN
# 2 Charlie 72 80.0
# 3 Diana 88 NaN
Fix 5: Use merge() for Cross-DataFrame Assignments
When the source values live in another DataFrame, use merge() on key columns — it handles index alignment automatically:
import pandas as pd
df = pd.DataFrame({"customer_id": [1001, 1002, 1003, 1004, 1005],
"revenue": [250, 180, 320, 90, 410]})
# Top 3 customers by revenue
top3 = df.nlargest(3, "revenue")[["customer_id"]].copy()
top3["rank"] = [1, 2, 3]
# merge() handles alignment — NaN for customers not in top3
df = df.merge(top3, on="customer_id", how="left")
print(df)
# customer_id revenue rank
# 0 1001 250 1.0
# 1 1002 180 NaN
# 2 1003 320 2.0
# 3 1004 90 NaN
# 4 1005 410 3.0
Quick Reference: Common Length Patterns
| Scenario | Source Length | Target Rows | Solution |
|---|---|---|---|
| Scalar assignment | 1 | N | df['col'] = scalar — broadcasts automatically |
| List assignment | M ≠ N | N | Match list length to N, or use map() |
| Column from same df | N | N | df['col'] = df['existing_col'] — always safe |
| groupby aggregate | G < N | N | df['col'] = grouped.reindex(df.index) |
| Filtered df assignment | Filtered N | Full N | Assign before filter, or reset_index(drop=True) |
| Dict/map assignment | N (via map) | N | df['col'] = df['key_col'].map(dict) |
How to Debug This Error in Practice
- Read the full error message. Python tells you both lengths:
Length of values (X) does not match length of index (Y). Note both numbers. - Print the shape of every source before assignment. Before
df['col'] = values, addprint(len(values), len(df))to confirm the lengths. - Check where the values came from. Did they originate from a
groupby(), amerge(), a filter, or a raw list? Each source has a different length guarantee. - Use
df.shapeandSeries.shapeproactively. Validating shapes before assignment is a one-line check that saves minutes of debugging. - For cross-DataFrame assignments, use
merge()orjoin()instead of raw column assignment — they handle index alignment automatically.
How to Prevent This Error
- Validate lengths before every column assignment. Add
assert len(values) == len(df)as a guardrail at the top of data transformation functions. - Use
map()instead of list assignment when values come from a key-value relationship —map()produces correctly-sized output. - Prefer column-from-column assignment.
df['new'] = df['existing'] + df['another']is always length-safe. Avoid mixing manually constructed lists with DataFrame columns. - Use
df.assign()for chained operations.df = df.assign(new_col=something)makes length mismatches easier to spot in review. - Write a helper function. A simple
safe_assign(df, col, values)that checks length and raises a clear error before pandas does prevents cryptic tracebacks in production pipelines.
Real-World Example: Fixing a Broken Data Pipeline
import pandas as pd
# Simulating a real data pipeline with mixed sources
df = pd.DataFrame({
"customer_id": [1001, 1002, 1003, 1004, 1005],
"revenue": [250, 180, 320, 90, 410],
"department": ["Sales", "Eng", "Sales", "Eng", "Sales"]
})
# RIGHT 1: Use map() for department-based bonus
dept_bonus = {"Sales": 5000, "Eng": 3000}
df["bonus"] = df["department"].map(dept_bonus)
# RIGHT 2: Use merge() for a lookup table
bonus_lookup = pd.DataFrame({
"department": ["Sales", "Eng"],
"bonus": [5000, 3000]
})
df = df.merge(bonus_lookup, on="department", how="left")
print(df)
# customer_id revenue department bonus
# 0 1001 250 Sales 5000
# 1 1002 180 Eng 3000
# 2 1003 320 Sales 5000
# 3 1004 90 Eng 3000
# 4 1005 410 Sales 5000
Frequently Asked Questions
Can I use a numpy array instead of a list for column assignment?
Yes — numpy arrays work exactly like lists for column assignment. The length check is the same: the array’s first dimension must equal len(df). Numpy arrays from operations like df['col'].values always have the correct length, but arrays constructed from scratch must be explicitly sized to match.
Why does this error appear even when I use df['col'] = df['other_col']?
Column-to-column assignment only fails if the source column has a different index that cannot be aligned. Use df['new'] = df['other'].values to use raw numpy values (ignoring index), or df['new'] = df['other'].reindex(df.index) to explicitly align with NaN fill for missing rows.
Does this error occur with pandas.Series as well?
Yes. Assigning to a Series with a mismatched index also raises ValueError: Length of values does not match length of index. The same principles apply: Series are row-aligned just like DataFrames.
What about MultiIndex DataFrames?
MultiIndex makes alignment more complex. After a groupby() on a MultiIndex, always use .reset_index() to convert back to a sequential integer index, or use .reindex() with the full MultiIndex to align before assignment.
Summary
ValueError: Length of values does not match length of index is pandas telling you that the number of values you are trying to assign does not match the number of rows in your DataFrame. The fixes are:
- Match lengths explicitly — ensure your list, Series, or array has the same number of elements as
len(df) - Use
map()— when values come from a key-value relationship,map(dict)produces correctly-sized output - Use
reset_index(drop=True)— after filtering or aggregation, reset the index before assigning - Use
reindex()— to align a mismatched Series index with your DataFrame - Use
merge()— for cross-DataFrame assignments, merge handles alignment automatically - Validate with
assert len(values) == len(df)— before assignment to catch the error early
Related Articles
If you found this guide useful, explore these related articles on PyBlog:
- pandas DataFrame Common Errors and How to Fix Them — a curated guide to the 10 most frequent pandas errors
- SettingWithCopyWarning: Causes and Fixes — another common pandas warning that signals a length or view problem
- Python Debugging: The Complete 2026 Guide — systematic debugging for every Python error

