pandas-dev/pandas · error · ValueError

dtype is not specified and cannot be inferred

Error message

dtype is not specified and cannot be inferred

What it means

Raised by PeriodArray.__init__ when, after all input-handling branches, dtype is still None. PeriodArray needs a frequency to interpret the int64 ordinals; without a PeriodDtype from either the dtype argument or an incoming PeriodArray/PeriodIndex, there is no way to know the freq, so construction fails. The values have already been coerced to int64, but the freq is missing.

Solutions

  1. Pass an explicit dtype: PeriodArray(ordinals, dtype='period[M]').
  2. Supply Period scalars instead of raw ints so the freq is inferred: PeriodArray([pd.Period('2023-01', freq='M'), ...]).
  3. Build with pd.period_range or pd.PeriodIndex which always carry a freq.

Example fix

# before
pd.PeriodArray(np.array([202301, 202302], dtype='int64'))  # raises

# after
pd.PeriodArray(np.array([202301, 202302], dtype='int64'), dtype='period[M]')
Defensive patterns

Strategy: validation

Validate before calling

import numpy as np
import pandas as pd

def period_array_from_ordinals(ordinals, freq):
    if freq is None:
        raise ValueError('freq must be provided when constructing from raw ordinals')
    ordinals = np.asarray(ordinals, dtype='int64')
    return pd.PeriodArray(ordinals, dtype=f'period[{freq}]')

Type guard

def has_period_freq(dtype_or_none) -> bool:
    from pandas.core.dtypes.dtypes import PeriodDtype
    return dtype_or_none is not None and isinstance(dtype_or_none, PeriodDtype)

Try / catch

try:
    pd.PeriodArray(values)
except ValueError as e:
    if 'cannot be inferred' in str(e):
        pd.PeriodArray(values, dtype='period[M]')  # supply freq
    else:
        raise

Prevention

When it happens

Trigger: PeriodArray(np.array([202301, 202302], dtype='int64')) — raw ints, no dtype. PeriodArray([1, 2, 3]) with no freq. Internal code that strips dtype and forgets to reattach it.

Common situations: Loading ordinals from storage without persisting the freq; hand-building a PeriodArray from integers; the Series/PeriodIndex branches were skipped because the input was a plain ndarray.

Related errors


AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11). Data as JSON: /api/errors/4e0f02b2dbfe1ecb. Report an issue: GitHub.

Appendix: source

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

        if isinstance(values, ABCSeries):
            values = values._values
            if not isinstance(values, type(self)):
                raise TypeError("Incorrect dtype")

        elif isinstance(values, ABCPeriodIndex):
            values = values._values

        if isinstance(values, type(self)):
            if dtype is not None and dtype != values.dtype:
                raise raise_on_incompatible(values, dtype.freq)
            values, dtype = values._ndarray, values.dtype

        if not copy:
            values = np.asarray(values, dtype="int64")
        else:
            values = np.array(values, dtype="int64", copy=copy)
        if dtype is None:
            raise ValueError("dtype is not specified and cannot be inferred")
        dtype = cast("PeriodDtype", dtype)
        NDArrayBacked.__init__(self, values, dtype)

    # error: Signature of "_simple_new" incompatible with supertype "NDArrayBacked"
    @classmethod
    def _simple_new(  # type: ignore[override]
        cls,
        values: npt.NDArray[np.int64],
        dtype: PeriodDtype,
    ) -> Self:
        # alias for PeriodArray.__init__
        assertion_msg = "Should be numpy array of type i8"
        assert isinstance(values, np.ndarray) and values.dtype == "i8", assertion_msg
        return cls(values, dtype=dtype)

    @classmethod
    def _from_sequence(
        cls,

View on GitHub (pinned to 3b7651241d)