pandas-dev/pandas · error · ValueError
cannot convert float NaN to integer
Error message
cannot convert float NaN to integer
What it means
Raised by _field_to_int64 when the input array has float dtype and contains NaN. Casting NaN to int64 silently yields a garbage ordinal, so pandas refuses, matching the scalar Period constructor's behavior.
Solutions
- Drop or impute missing field values before constructing the PeriodIndex.
- Use fillna on the offending column with a sensible default or dropna() the rows.
- If missingness is meaningful, build a PeriodIndex for the valid subset and reindex.
Example fix
# before year = df['year'].astype(float) # contains NaN pd.PeriodIndex(year=year, quarter=df['q'], freq='Q') # after mask = df['year'].notna() pd.PeriodIndex(year=df.loc[mask,'year'].astype(int), quarter=df.loc[mask,'q'], freq='Q')
Defensive patterns
Strategy: validation
Validate before calling
import numpy as np
def fields_are_castable_to_int(values) -> bool:
arr = np.asarray(values)
if arr.dtype.kind == 'f':
return not np.isnan(arr).any()
return True Type guard
def has_no_nan_float(values) -> bool:
arr = np.asarray(values)
return arr.dtype.kind != 'f' or not bool(np.isnan(arr).any()) Try / catch
try:
pi = pd.PeriodIndex(year=y, quarter=q, freq='Q')
except ValueError as e:
if 'cannot convert float NaN' in str(e):
mask = np.asarray(y, dtype=float) == np.asarray(y, dtype=float)
pi = pd.PeriodIndex(year=np.asarray(y)[mask], quarter=np.asarray(q)[mask], freq='Q')
else:
raise Prevention
- Dropna field columns before constructing PeriodIndex.
- Use integer dtype for year/quarter/month to surface NaN earlier as a different error.
- Validate kind=='f' columns with np.isnan(...).any() before passing.
When it happens
Trigger: Passing a year/month/quarter/hour/... field built from a float column with missing values to PeriodIndex field-based construction; year = pd.Series([2020.0, np.nan]) used as the year field.
Common situations: Joining onto a dimension table that left nulls; user-uploaded spreadsheets with blank cells; downstream of merge that introduced NaNs.
Related errors
- Cannot cast NaN value to Integer dtype.
- ArrowStringArray requires a PyArrow (chunked) array of…
- 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/4f37d30f02f23424.
Report an issue: GitHub.
Appendix: source
Thrown at pandas/core/arrays/period.py:1636
ordinals = libperiod.period_ordinals_from_fields(
_field_to_int64(arrays[0]),
_field_to_int64(arrays[1]),
_field_to_int64(arrays[2]),
_field_to_int64(arrays[3]),
_field_to_int64(arrays[4]),
_field_to_int64(arrays[5]),
base,
)
return ordinals, freq
def _field_to_int64(values) -> np.ndarray:
values = np.asarray(values)
if values.dtype.kind == "f" and np.isnan(values).any():
# Match the error raised by the scalar Period constructor; casting
# NaN to int64 would otherwise silently produce garbage ordinals.
raise ValueError("cannot convert float NaN to integer")
return values.astype(np.int64, copy=False)
def _make_field_arrays(*fields) -> list[np.ndarray]:
length = None
for x in fields:
if isinstance(x, (list, tuple, np.ndarray, ABCSeries)):
if length is not None and len(x) != length:
raise ValueError("Mismatched Period array lengths")
if length is None:
length = len(x)
# error: Argument 2 to "repeat" has incompatible type "Optional[int]"; expected
# "Union[Union[int, integer[Any]], Union[bool, bool_], ndarray, Sequence[Union[int,
# integer[Any]]], Sequence[Union[bool, bool_]], Sequence[Sequence[Any]]]"
return [
(
np.asarray(x)View on GitHub (pinned to 3b7651241d)