pandas-dev/pandas · error · ValueError

Period dtypes are not supported, use a PeriodIndex instead

Error message

Period dtypes are not supported, use a PeriodIndex instead

What it means

Raised when `left` is a `PeriodIndex`. Period intervals are not supported inside IntervalArray because periods need their own array semantics; pandas directs users to PeriodIndex (or interval over the period ordinal codes).

Solutions

  1. Convert periods to timestamps: `left.to_timestamp()` and `right.to_timestamp()` then build the IntervalArray over DatetimeIndex.
  2. Operate on period ordinals: `left.astype('int64')` (the underlying ordinal) if you only need ordering.
  3. Keep endpoints as a PeriodIndex and do not wrap them in an IntervalArray.

Example fix

# before
IntervalArray.from_arrays(pd.period_range('2020', periods=2, freq='M'), pd.period_range('2020-02', periods=2, freq='M'))

# after
pli = pd.period_range('2020', periods=2, freq='M')
pri = pd.period_range('2020-02', periods=2, freq='M')
IntervalArray.from_arrays(pli.to_timestamp(), pri.to_timestamp())
Defensive patterns

Strategy: validation

Validate before calling

import pandas as pd

def to_interval_bounds(left, right):
    if isinstance(left, pd.PeriodIndex):
        left = left.to_timestamp()
    if isinstance(right, pd.PeriodIndex):
        right = right.to_timestamp()
    return left, right

Type guard

import pandas as pd

def has_no_period_bounds(left, right) -> bool:
    return not isinstance(left, pd.PeriodIndex) and not isinstance(right, pd.PeriodIndex)

Try / catch

try:
    arr = IntervalArray.from_arrays(left, right)
except ValueError as e:
    if 'Period dtypes are not supported' in str(e):
        arr = IntervalArray.from_arrays(left.to_timestamp(), right.to_timestamp())
    else:
        raise

Prevention

When it happens

Trigger: `IntervalArray.from_arrays(pd.period_range('2020', periods=3, freq='M'), pd.period_range('2020-03', periods=3, freq='M'))`; converting a DataFrame with period columns into an interval index.

Common situations: Time-bucketing workflows that naturally produce PeriodIndex endpoints; users wanting 'period intervals' (e.g. terms spanning months).

Related errors


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

Appendix: source

Thrown at pandas/core/arrays/interval.py:337

            msg = (
                f"must not have differing left [{type(left).__name__}] and "
                f"right [{type(right).__name__}] types"
            )
            raise ValueError(msg)
        if (
            isinstance(left.dtype, CategoricalDtype)
            or is_string_dtype(left.dtype)
            or is_string_dtype(right.dtype)
        ):
            # GH 19016, GH 66518: reject unsupported right-side dtypes too.
            msg = (
                "category, object, and string subtypes are not supported "
                "for IntervalArray"
            )
            raise TypeError(msg)
        if isinstance(left, ABCPeriodIndex):
            msg = "Period dtypes are not supported, use a PeriodIndex instead"
            raise ValueError(msg)
        if isinstance(left, ABCDatetimeIndex) and str(left.tz) != str(right.tz):
            msg = (
                "left and right must have the same time zone, got "
                f"'{left.tz}' and '{right.tz}'"
            )
            raise ValueError(msg)
        elif needs_i8_conversion(left.dtype) and left.unit != right.unit:
            # e.g. m8[s] vs m8[ms], try to cast to a common dtype GH#55714
            left_arr, right_arr = left._data._ensure_matching_resos(right._data)
            left = ensure_index(left_arr)
            right = ensure_index(right_arr)

        # For dt64/td64 we want DatetimeArray/TimedeltaArray instead of ndarray
        left = ensure_wrapped_if_datetimelike(left)
        left = extract_array(left, extract_numpy=True)
        right = ensure_wrapped_if_datetimelike(right)
        right = extract_array(right, extract_numpy=True)

View on GitHub (pinned to 3b7651241d)