pandas-dev/pandas · error · TypeError

PeriodArray does not allow floating point in construction

Error message

PeriodArray does not allow floating point in construction

What it means

Raised by PeriodArray._from_sequence when the coerced input has float dtype and contains at least one non-NaN value. Period ordinals are integers by definition, so genuine floating-point data cannot be interpreted as periods; only all-NaN float arrays are tolerated (interpreted as all-NaT).

Source

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

                return scalars.copy()
            return scalars

        if not isinstance(
            scalars, (np.ndarray, list, tuple, ABCSeries, ABCIndex, ExtensionArray)
        ):
            # test_constructor_empty_special has a case with an iter object
            scalars = list(scalars)

        if isinstance(scalars, ExtensionArray) and scalars.dtype.kind in "iu":
            # e.g. masked or arrow-backed integer array; np.asarray would cast
            #  integers-with-NA to float and raise a misleading "floating point"
            #  error below, so route through object dtype to keep the integers.
            scalars = scalars.to_numpy(dtype=object, na_value=NaT)

        arrdata = np.asarray(scalars)
        if arrdata.dtype.kind == "f" and len(arrdata) > 0:
            if not lib.all_nans(arrdata):
                raise TypeError(
                    "PeriodArray does not allow floating point in construction"
                )
            ordinals = np.full(arrdata.shape, iNaT, dtype=np.int64)
            return cls(ordinals, dtype=dtype)

        elif arrdata.dtype.kind in "iu":
            arr = arrdata.astype(np.int64, copy=False)
            ordinals = libperiod.from_calendar_ordinals(arr, dtype)  # type: ignore[arg-type]
            return cls(ordinals, dtype=dtype)
        else:
            periods = ensure_object(arrdata)

            if dtype is None:
                dtype_base = libperiod.extract_period_unit(periods)
                dtype = PeriodDtype(dtype_base)
            ordinals = libperiod.extract_ordinals(periods, dtype)  # type: ignore[arg-type]
            return cls(ordinals, dtype=dtype)

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Cast to integer first: np.asarray(data, dtype='int64') (only safe if no fractional part).
  2. Drop or NaN-out fractional values, then construct from strings/Period objects.
  3. Build from Period objects or ISO strings via pd.period_array(['2020-01-01', ...]).

Example fix

# before
pd.period_array([2020.5, 2021.0], dtype=pd.PeriodDtype('Y'))
# after
pd.period_array([2020, 2021], dtype=pd.PeriodDtype('Y'))
# or from strings
pd.period_array(['2020','2021'], dtype=pd.PeriodDtype('Y'))
Defensive patterns

Strategy: validation

Validate before calling

import numpy as np
import pandas as pd

def to_period_safe(data, freq):
    arr = np.asarray(data)
    if arr.dtype.kind == 'f':
        if not pd.isna(arr).all() and not np.all(np.equal(np.mod(arr, 1), 0)):
            raise ValueError('data has fractional floats; cannot be periods')
        arr = arr.astype('int64', copy=False)
    return pd.period_array(arr, dtype=pd.PeriodDtype(freq))

Type guard

import numpy as np

def is_integer_or_all_nan_float(arr) -> bool:
    a = np.asarray(arr)
    if a.dtype.kind == 'i':
        return True
    if a.dtype.kind == 'f':
        return bool(np.all(np.isnan(a)) or np.all(np.equal(np.mod(a, 1), 0)))
    return False

Try / catch

try:
    pa = pd.period_array(data, dtype=pd.PeriodDtype(freq))
except TypeError:
    pa = pd.period_array(np.asarray(data, dtype='int64'), dtype=pd.PeriodDtype(freq))

Prevention

When it happens

Trigger: pd.period_array([1.5, 2.0], dtype=...), pd.PeriodIndex([3.14]), or feeding a float Series into a period dtype. Numeric columns with NaN that get cast to float before being treated as periods but contain real fractional values.

Common situations: Reading a CSV column of years as float (2020.0) and trying to build a PeriodIndex. Mixing NaN with integer-like data producing float dtype. Off-by-one casts from nullable Int64 to Float64.

Related errors


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