pandas-dev/pandas · error · TypeError
'std' and 'sem' are not valid for PeriodDtype
Error message
'std' and 'sem' are not valid for PeriodDtype
What it means
Raised inside the std/sem branch of the groupby reduce path when self.dtype is a PeriodDtype. Standard deviation and standard error require arithmetic on magnitudes, but a Period is an ordinal label tied to a frequency, so dispersion statistics are undefined. The guard fires after the ordinal computation but before attempting to build the result.
Source
Thrown at pandas/core/arrays/datetimelike.py:1675
min_count=min_count,
ngroups=ngroups,
comp_ids=ids,
mask=None,
**kwargs,
)
if op.how in op.cast_blocklist:
# i.e. how in ["rank"], since other cast_blocklist methods don't go
# through cython_operation
return res_values
# We did a view to M8[ns] above, now we go the other direction
assert res_values.dtype == "M8[ns]"
if how in ["std", "sem"]:
from pandas.core.arrays import TimedeltaArray
if isinstance(self.dtype, PeriodDtype):
raise TypeError("'std' and 'sem' are not valid for PeriodDtype")
self = cast("DatetimeArray | TimedeltaArray", self)
new_dtype = f"m8[{self.unit}]"
res_values = res_values.view(new_dtype)
return TimedeltaArray._simple_new(res_values, dtype=res_values.dtype)
res_values = res_values.view(self._ndarray.dtype)
return self._from_backing_data(res_values)
def _groupby_quantile(
self,
*,
qs: npt.NDArray[np.float64],
interpolation: Literal["linear", "lower", "higher", "nearest", "midpoint"],
ids: npt.NDArray[np.intp],
ngroups: int,
starts: npt.NDArray[np.int64],
ends: npt.NDArray[np.int64],
) -> ArrayLike:View on GitHub (pinned to 71959b8cb9)
Solutions
- Drop std/sem from the aggregation for period columns.
- If you need spread, convert to an ordinal integer with .astype('int64') (the period ordinal) or to Timestamp with .to_timestamp() and compute on the resulting datetime values.
- Use .value_counts() or nunique() for period-distribution summaries instead.
Example fix
# before
pd.period_range('2020-01','2020-05',freq='M').to_series().std()
# after
ordinals = pd.period_range('2020-01','2020-05',freq='M').astype('int64')
ordinals.std() Defensive patterns
Strategy: validation
Validate before calling
if pd.api.types.is_period_dtype(s) and any(op in {'std','sem'} for op in ops):
raise ValueError('Period columns do not support std/sem') Type guard
def is_period_column(s) -> bool:
return isinstance(s.dtype, pd.PeriodDtype) Try / catch
try:
s.std()
except TypeError as e:
if 'not valid for PeriodDtype' in str(e):
s.astype('int64').std()
else: raise Prevention
- Exclude std/sem from describe() output for period columns.
- Tag period columns in metadata and route them to value_counts/nunique summaries.
When it happens
Trigger: Calling .std() or .sem() on a PeriodIndex, PeriodArray, or a Series of Period dtype, or df.groupby('g')['period_col'].std(). Also reachable via Series.agg(['mean','std']) on a period column.
Common situations: Running describe()/agg() pipelines over period-encoded data (monthly reporting periods, fiscal quarters, hour-of-week periods). Treating a Period column like a datetime in a stats template.
Related errors
- Period type does not support {how} operations
- timedelta64 type does not support {how} operations
- mean is not implemented for {type(self).__name__} since the
- datetime64 type does not support operation '{how}'
- '{how}' with PeriodDtype is no longer supported. Use (obj !=
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/bce5cbfda5de70b6.
Report an issue: GitHub.