{"record":{"id":"4f37d30f02f23424","repo":"pandas-dev/pandas","slug":"cannot-convert-float-nan-to-integer-4f37d3","errorCode":null,"errorMessage":"cannot convert float NaN to integer","messagePattern":"cannot convert float NaN to integer","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/period.py","lineNumber":1633,"sourceCode":"        ordinals = libperiod.period_ordinals_from_fields(\n            _field_to_int64(arrays[0]),\n            _field_to_int64(arrays[1]),\n            _field_to_int64(arrays[2]),\n            _field_to_int64(arrays[3]),\n            _field_to_int64(arrays[4]),\n            _field_to_int64(arrays[5]),\n            base,\n        )\n\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)","sourceCodeStart":1615,"sourceCodeEnd":1651,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/period.py#L1615-L1651","documentation":"Raised in _field_to_int64 when a float-typed year/quarter/day/etc field contains NaN. Casting NaN to int64 would produce a garbage ordinal (a huge negative integer), so pandas explicitly mirrors the scalar Period constructor's error. It guards _range_from_fields' vectorized path.","triggerScenarios":"period_range(year=[2020, np.nan], quarter=[1,2], freq='Q'); a year Series with missing values passed to period_range; float columns (e.g. years stored as float64 because of NaNs) reaching the period constructor.","commonSituations":"CSV years parsed as float because of empty cells; joins/groupbys introducing NaNs into year/quarter columns; nullable integer columns upcast to float by an operation.","solutions":["Drop or fill NaN rows before building the period range: df = df.dropna(subset=['year']).","Convert the year column to a nullable Int64 and fill: df['year'] = df['year'].astype('Int64').fillna(0).astype(int).","Filter to non-null fields: mask = df[['year','quarter']].notna().all(axis=1)."],"exampleFix":"// before\nrng = pd.period_range(year=df['year'], quarter=df['quarter'], freq='Q')\n// after\nclean = df.dropna(subset=['year','quarter'])\nrng = pd.period_range(year=clean['year'].astype(int), quarter=clean['quarter'].astype(int), freq='Q')","handlingStrategy":"validation","validationCode":"import pandas as pd\nimport numpy as np\n\ndef period_range_safe(year, quarter, freq='Q'):\n    y = pd.Series(year)\n    q = pd.Series(quarter)\n    mask = y.notna() & q.notna()\n    return pd.period_range(year=y[mask].astype(int), quarter=q[mask].astype(int), freq=freq)","typeGuard":"def no_nan_float_field(field) -> bool:\n    import numpy as np\n    arr = np.asarray(field, dtype=float)\n    return not np.isnan(arr).any()","tryCatchPattern":"try:\n    rng = pd.period_range(year=year, quarter=quarter, freq='Q')\nexcept ValueError as e:\n    if 'cannot convert float NaN' in str(e):\n        clean = pd.DataFrame({'y': year, 'q': quarter}).dropna()\n        rng = pd.period_range(year=clean['y'].astype(int), quarter=clean['q'].astype(int), freq='Q')\n    else:\n        raise","preventionTips":["dropna() on year/quarter columns before constructing periods.","Prefer nullable Int64 dtypes to detect missing years.","Avoid float dtypes for year/quarter fields."],"tags":["pandas","period","period-range","nan","dtype-coercion"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}