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
- Convert periods to timestamps: `left.to_timestamp()` and `right.to_timestamp()` then build the IntervalArray over DatetimeIndex.
- Operate on period ordinals: `left.astype('int64')` (the underlying ordinal) if you only need ordering.
- 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
- Convert PeriodIndex endpoints to timestamps before building IntervalArray.
- Keep period-bounded data as PeriodIndex rather than forcing into IntervalArray.
- Document endpoint-type requirements in library wrappers.
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
- Cannot modify read-only array
- category, object, and string subtypes are not supported for…
- closed keyword does not match dtype.closed
- invalid dtype
- left and right must have the same length
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)