pandas-dev/pandas · error · ValueError
Invalid dtype for PeriodArray
Error message
Invalid dtype {dtype} for PeriodArray What it means
Raised by PeriodArray.__init__ when a dtype argument is supplied, resolved via pandas_dtype, but is not a PeriodDtype. PeriodArray is meaningful only with a frequency; passing an incompatible dtype (e.g. int64, datetime64, a string like 'M' that isn't a period unit) is rejected. The resolved dtype is included in the message.
Solutions
- Pass a proper period dtype: dtype='period[M]' or dtype=PeriodDtype('M').
- Omit dtype and let pandas infer the freq from Period scalars in the input.
- Build via pd.period_range(start, end, freq='M') which handles dtype for you.
Example fix
# before
pd.PeriodArray(pd.Series([pd.Period('2023', freq='Y')]), dtype='int64') # raises
# after
pd.PeriodArray(pd.Series([pd.Period('2023', freq='Y')]), dtype='period[Y') Defensive patterns
Strategy: validation
Validate before calling
import pandas as pd
def make_period_array(values, freq=None):
dtype = f'period[{freq}]' if freq else None
if dtype is not None:
pd.core.dtypes.common.pandas_dtype(dtype) # raises early if invalid
return pd.PeriodArray(values, dtype=dtype) Type guard
from pandas.core.dtypes.dtypes import PeriodDtype
def is_period_dtype_like(dtype) -> bool:
try:
return isinstance(pd.core.dtypes.common.pandas_dtype(dtype), PeriodDtype)
except TypeError:
return False Try / catch
try:
pd.PeriodArray(values, dtype=dtype)
except ValueError as e:
if 'Invalid dtype' in str(e):
pd.PeriodArray(values, dtype=f'period[{dtype}]')
else:
raise Prevention
- Always use the 'period[<freq>]' form for period dtypes (e.g. 'period[M]').
- Use pd.period_range() / pd.PeriodIndex() which manage dtype for you.
- Don't confuse period freq strings with numpy datetime64 units.
When it happens
Trigger: PeriodArray([2023, 2024], dtype='int64'); PeriodArray(values, dtype='datetime64[ns]'); PeriodArray(values, dtype='M') where 'M' parses to a non-Period dtype. Direct constructor use with the wrong dtype kind.
Common situations: Confusing Period freq strings ('M' = month period) with numpy/dateutil units; passing a plain frequency string where a period dtype ('period[M]') is required; copy-pasting dtype from a DatetimeIndex.
Related errors
- dtype is not specified and cannot be inferred
- Incorrect dtype
- Cannot add or subtract timedelta64[ns] dtype from
- Cannot add/subtract timedelta-like from PeriodArray that is…
- Could not infer freq from start/end
AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11).
Data as JSON: /api/errors/1dbd15a7486ee6f8.
Report an issue: GitHub.
Appendix: source
Thrown at pandas/core/arrays/period.py:230
"days_in_month",
]
# GH#46768 - deprecated but still need to be accessible via .dt accessor
_deprecated_ops: list[str] = ["dayofweek", "dayofyear", "daysinmonth"]
_datetimelike_ops: list[str] = (
_field_ops + _object_ops + _bool_ops + _deprecated_ops
)
_datetimelike_methods: list[str] = ["strftime", "to_timestamp", "asfreq"]
_dtype: PeriodDtype
# --------------------------------------------------------------------
# Constructors
def __init__(self, values, dtype: Dtype | None = None, copy: bool = False) -> None:
if dtype is not None:
dtype = pandas_dtype(dtype)
if not isinstance(dtype, PeriodDtype):
raise ValueError(f"Invalid dtype {dtype} for PeriodArray")
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)View on GitHub (pinned to 3b7651241d)