Skip to content

ValueError: Length of values does not match length of index

Have you assigned a list to a new column and been told the lengths disagree?

sales = pd.DataFrame({'region': ['North', 'South', 'North'],
                      'revenue': [100, 250, 175]})

sales.assign(tax=[1, 2])
ValueError: Length of values (2) does not match length of index (3)

The numbers in the message are the whole diagnosis: you supplied two values for three rows. Pandas will not recycle, pad or truncate, because every one of those would be a guess about data.

If the value is the same for every row, give it once and let Pandas broadcast:

sales.assign(tax=0.2)
  region  revenue  tax
0  North      100  0.2
1  South      250  0.2
2  North      175  0.2

The filtered-frame trap

The version that costs real time looks like this. You filter, compute something from the filtered rows, and assign it back to the original frame:

big = sales[sales['revenue'] > 150]
sales['big_revenue'] = big['revenue'] * 2

Two rows of results, three rows of frame. The lengths disagree because the filter changed one and not the other.

What makes it confusing is that the equivalent assignment on the filtered frame is a different problem again, and in Pandas 3 raises ChainedAssignmentError rather than silently doing nothing. The habit worth building is to compute across the whole frame and let the condition decide, rather than slicing and assigning back:

sales.assign(big_revenue=(sales['revenue'] * 2).where(sales['revenue'] > 150))

Every row gets an answer, and the rows that fail the condition get NaN rather than a length mismatch.

When the index is the real problem

If the lengths match and you still get a surprise, the index is usually why. Assigning a Series aligns on index labels, not on position:

sales['flag'] = pd.Series([True, False, True], index=[7, 8, 9])

That runs without error and fills the column with NaN, because no label matches. When you want positional assignment from a Series, .values or .to_numpy() strips the index and gives Pandas a plain array:

sales['flag'] = pd.Series([True, False, True], index=[7, 8, 9]).values

This is the mirror image of the length error: one raises loudly, the other says nothing and hands you a column of nulls.

The mistakes I see most often

Building the values with a list comprehension over the wrong thing. Iterating over a filtered frame, or over a dictionary, and assigning the result back to the full frame. The count comes from whatever you looped over.

Trusting len(df) after a chained operation. drop_duplicates, dropna and query all change the row count, and code written against the pre-filter length keeps working until the data changes.

Reading "length of index" as something exotic. It is just the number of rows.

Practice

See assign in Pandas for adding columns, and where in Pandas for applying a value only to the rows that qualify.