{"record":{"id":"2bb63d31cfa9a852","repo":"pandas-dev/pandas","slug":"periodarray-does-not-allow-floating-point-in-const","errorCode":null,"errorMessage":"PeriodArray does not allow floating point in construction","messagePattern":"PeriodArray does not allow floating point in construction","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/period.py","lineNumber":307,"sourceCode":"                return scalars.copy()\n            return scalars\n\n        if not isinstance(\n            scalars, (np.ndarray, list, tuple, ABCSeries, ABCIndex, ExtensionArray)\n        ):\n            # test_constructor_empty_special has a case with an iter object\n            scalars = list(scalars)\n\n        if isinstance(scalars, ExtensionArray) and scalars.dtype.kind in \"iu\":\n            # e.g. masked or arrow-backed integer array; np.asarray would cast\n            #  integers-with-NA to float and raise a misleading \"floating point\"\n            #  error below, so route through object dtype to keep the integers.\n            scalars = scalars.to_numpy(dtype=object, na_value=NaT)\n\n        arrdata = np.asarray(scalars)\n        if arrdata.dtype.kind == \"f\" and len(arrdata) > 0:\n            if not lib.all_nans(arrdata):\n                raise TypeError(\n                    \"PeriodArray does not allow floating point in construction\"\n                )\n            ordinals = np.full(arrdata.shape, iNaT, dtype=np.int64)\n            return cls(ordinals, dtype=dtype)\n\n        elif arrdata.dtype.kind in \"iu\":\n            # GH#64227 enforcing means dropping from_calendar_ordinals here and\n            #  reading arrdata as ordinals; the object-dtype and Period-scalar\n            #  paths in tslibs.period must be enforced at the same time or the\n            #  two interpretations diverge again.\n            warnings.warn(\n                INT_TO_PERIOD_DEPR_MSG,\n                Pandas4Warning,\n                stacklevel=find_stack_level(),\n            )\n            arr = arrdata.astype(np.int64, copy=False)\n            ordinals = libperiod.from_calendar_ordinals(arr, dtype)  # type: ignore[arg-type]\n            return cls(ordinals, dtype=dtype)","sourceCodeStart":289,"sourceCodeEnd":325,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/arrays/period.py#L289-L325","documentation":"Raised by PeriodArray._from_sequence when the input coerces to a float ndarray that contains any non-NaN value. PeriodArray construction from float is only tolerated when every element is NaN (treated as NaT); meaningful floats are rejected because periods are defined by integer ordinals + freq, not by floating values. This prevents accidentally constructing periods from e.g. decimal years.","triggerScenarios":"pd.array([2023.0, 2024.0], dtype='period[Y]'); pd.PeriodIndex([1.5, 2.5], freq='M'); feeding a Float64 nullable column into a period constructor without first converting to int ordinals or Period strings.","commonSituations":"Year-as-float data (2023.5); downstream of nullable integer arrays whose NaNs forced a float cast; CSV columns read as float that semantically represent period ordinals.","solutions":["Convert floats to int ordinals first: pd.array(np.asarray(values, dtype='int64'), dtype='period[M]').","Pass Period scalars or period strings: pd.period_array([pd.Period('2023', freq='Y'), ...]).","Keep all-NaN float arrays if the intent is an all-NaT result (that path is allowed)."],"exampleFix":"# before\npd.array([2023.0, 2024.0], dtype='period[Y]')  # raises\n\n# after\npd.array(np.array([2023, 2024], dtype='int64'), dtype='period[Y]')","handlingStrategy":"validation","validationCode":"import numpy as np\n\ndef period_array_safe(values, freq):\n    arr = np.asarray(values)\n    if arr.dtype.kind == 'f':\n        if np.isnan(arr).all():\n            return pd.period_array([pd.NaT] * len(arr), freq=freq)\n        arr = arr.astype('int64', copy=False)\n    return pd.array(arr, dtype=f'period[{freq}]')","typeGuard":"import numpy as np\n\ndef is_integer_or_allnan_float(values) -> bool:\n    arr = np.asarray(values)\n    return arr.dtype.kind in 'iu' or (arr.dtype.kind == 'f' and bool(np.isnan(arr).all()))","tryCatchPattern":"try:\n    pd.array(values, dtype=f'period[{freq}]')\nexcept TypeError as e:\n    if 'floating point' in str(e):\n        pd.array(np.asarray(values, dtype='int64'), dtype=f'period[{freq}]')\n    else:\n        raise","preventionTips":["Cast float ordinal columns to int64 before constructing a PeriodArray.","Pass Period scalars or period strings instead of numeric stand-ins.","Audit year/quarter columns stored as float for accidental non-integer values."],"tags":["pandas","period","constructor","float","ordinal"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}