pandas-dev/pandas · error · ValueError

Mismatched Period array lengths

Error message

Mismatched Period array lengths

What it means

Raised in _make_field_arrays when the list-like field arguments (year, quarter, month, day, ...) passed to period_range have inconsistent lengths. The vectorized ordinal builder requires broadcastable inputs, so unequal arrays are rejected before numpy would raise a confusing broadcast error.

Source

Thrown at pandas/core/arrays/period.py:1642

    return ordinals, freq


def _field_to_int64(values) -> np.ndarray:
    values = np.asarray(values)
    if values.dtype.kind == "f" and np.isnan(values).any():
        # Match the error raised by the scalar Period constructor; casting
        #  NaN to int64 would otherwise silently produce garbage ordinals.
        raise ValueError("cannot convert float NaN to integer")
    return values.astype(np.int64, copy=False)


def _make_field_arrays(*fields) -> list[np.ndarray]:
    length = None
    for x in fields:
        if isinstance(x, (list, tuple, np.ndarray, ABCSeries)):
            if length is not None and len(x) != length:
                raise ValueError("Mismatched Period array lengths")
            if length is None:
                length = len(x)

    # error: Argument 2 to "repeat" has incompatible type "Optional[int]"; expected
    # "Union[Union[int, integer[Any]], Union[bool, bool_], ndarray, Sequence[Union[int,
    # integer[Any]]], Sequence[Union[bool, bool_]], Sequence[Sequence[Any]]]"
    return [
        (
            np.asarray(x)
            if isinstance(x, (np.ndarray, list, tuple, ABCSeries))
            else np.repeat(x, length)  # type: ignore[arg-type]
        )
        for x in fields
    ]

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Align the source DataFrames on their index before extracting year/quarter, or reset_index(drop=True) on both.
  2. Assert equal lengths up front: assert len(year) == len(quarter).
  3. Pass scalars for fields that don't vary instead of repeating arrays.

Example fix

// before
rng = pd.period_range(year=df_a['year'], quarter=df_b['quarter'], freq='Q')
// after
merged = df_a[['year']].join(df_b[['quarter']], how='inner')
rng = pd.period_range(year=merged['year'], quarter=merged['quarter'], freq='Q')
Defensive patterns

Strategy: validation

Validate before calling

import pandas as pd
import numpy as np

def period_range_aligned(year, quarter, freq='Q'):
    arrays = [x for x in (year, quarter) if isinstance(x, (list, tuple, np.ndarray, pd.Series))]
    lengths = {len(x) for x in arrays}
    if len(lengths) > 1:
        raise ValueError(f'mismatched lengths: {sorted(lengths)}')
    return pd.period_range(year=year, quarter=quarter, freq=freq)

Type guard

def same_length_listlikes(*fields) -> bool:
    import numpy as np, pandas as pd
    lens = {len(x) for x in fields if isinstance(x, (list, tuple, np.ndarray, pd.Series))}
    return len(lens) <= 1

Try / catch

try:
    rng = pd.period_range(year=year, quarter=quarter, freq='Q')
except ValueError as e:
    if 'Mismatched Period array lengths' in str(e):
        n = min(len(year), len(quarter))
        rng = pd.period_range(year=year[:n], quarter=quarter[:n], freq='Q')
    else:
        raise

Prevention

When it happens

Trigger: period_range(year=[2020,2021], quarter=[1,2,3], freq='Q'); mixing a length-2 year column with a length-3 quarter column from misaligned DataFrames; scalar fields are broadcast so only list-likes need to match.

Common situations: Field arrays pulled from different DataFrames that were filtered differently; off-by-one slicing when building year/quarter vectors; concat misalignment.

Related errors


AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07). Data as JSON: /api/errors/a2681b971b3f883b. Report an issue: GitHub.