{"record":{"id":"a2681b971b3f883b","repo":"pandas-dev/pandas","slug":"mismatched-period-array-lengths","errorCode":null,"errorMessage":"Mismatched Period array lengths","messagePattern":"Mismatched Period array lengths","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/period.py","lineNumber":1642,"sourceCode":"\n    return ordinals, freq\n\n\ndef _field_to_int64(values) -> np.ndarray:\n    values = np.asarray(values)\n    if values.dtype.kind == \"f\" and np.isnan(values).any():\n        # Match the error raised by the scalar Period constructor; casting\n        #  NaN to int64 would otherwise silently produce garbage ordinals.\n        raise ValueError(\"cannot convert float NaN to integer\")\n    return values.astype(np.int64, copy=False)\n\n\ndef _make_field_arrays(*fields) -> list[np.ndarray]:\n    length = None\n    for x in fields:\n        if isinstance(x, (list, tuple, np.ndarray, ABCSeries)):\n            if length is not None and len(x) != length:\n                raise ValueError(\"Mismatched Period array lengths\")\n            if length is None:\n                length = len(x)\n\n    # error: Argument 2 to \"repeat\" has incompatible type \"Optional[int]\"; expected\n    # \"Union[Union[int, integer[Any]], Union[bool, bool_], ndarray, Sequence[Union[int,\n    # integer[Any]]], Sequence[Union[bool, bool_]], Sequence[Sequence[Any]]]\"\n    return [\n        (\n            np.asarray(x)\n            if isinstance(x, (np.ndarray, list, tuple, ABCSeries))\n            else np.repeat(x, length)  # type: ignore[arg-type]\n        )\n        for x in fields\n    ]\n","sourceCodeStart":1624,"sourceCodeEnd":1657,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/period.py#L1624-L1657","documentation":"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.","triggerScenarios":"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.","commonSituations":"Field arrays pulled from different DataFrames that were filtered differently; off-by-one slicing when building year/quarter vectors; concat misalignment.","solutions":["Align the source DataFrames on their index before extracting year/quarter, or reset_index(drop=True) on both.","Assert equal lengths up front: assert len(year) == len(quarter).","Pass scalars for fields that don't vary instead of repeating arrays."],"exampleFix":"// before\nrng = pd.period_range(year=df_a['year'], quarter=df_b['quarter'], freq='Q')\n// after\nmerged = df_a[['year']].join(df_b[['quarter']], how='inner')\nrng = pd.period_range(year=merged['year'], quarter=merged['quarter'], freq='Q')","handlingStrategy":"validation","validationCode":"import pandas as pd\nimport numpy as np\n\ndef period_range_aligned(year, quarter, freq='Q'):\n    arrays = [x for x in (year, quarter) if isinstance(x, (list, tuple, np.ndarray, pd.Series))]\n    lengths = {len(x) for x in arrays}\n    if len(lengths) > 1:\n        raise ValueError(f'mismatched lengths: {sorted(lengths)}')\n    return pd.period_range(year=year, quarter=quarter, freq=freq)","typeGuard":"def same_length_listlikes(*fields) -> bool:\n    import numpy as np, pandas as pd\n    lens = {len(x) for x in fields if isinstance(x, (list, tuple, np.ndarray, pd.Series))}\n    return len(lens) <= 1","tryCatchPattern":"try:\n    rng = pd.period_range(year=year, quarter=quarter, freq='Q')\nexcept ValueError as e:\n    if 'Mismatched Period array lengths' in str(e):\n        n = min(len(year), len(quarter))\n        rng = pd.period_range(year=year[:n], quarter=quarter[:n], freq='Q')\n    else:\n        raise","preventionTips":["reset_index(drop=True) on source frames before extracting fields.","Assert len(year)==len(quarter) before calling period_range.","Pass scalars for invariant fields."],"tags":["pandas","period","period-range","shape-mismatch","broadcast"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}