
在 LeetCode 等受限环境中,直接对 datetime64[ns] 列使用 .dt.to_period('M') 并赋值回原列,会导致 to_json() 序列化时触发无限递归并抛出 OverflowError;根本解决方式是将 Period 类型显式转为字符串。
在 leetcode 等受限环境中,直接对 `datetime64[ns]` 列使用 `.dt.to_period('m')` 并赋值回原列,会导致 `to_json()` 序列化时触发无限递归并抛出 `overflowerror`;根本解决方式是将 period 类型显式转为字符串。
LeetCode 的评测系统在输出结果前会调用 DataFrame.to_json(orient='split') 进行序列化,而 pandas.Period 类型(尤其是通过 .dt.to_period() 生成的对象)在某些旧版 pandas + ujson 组合下存在序列化缺陷——它可能引发内部递归调用,最终超出 Python 默认递归限制,报错 OverflowError: Maximum recursion level reached。
⚠️ 关键误区:
- ❌
transactions['trans_date'] = transactions['trans_date'].dt.to_period('M')
→ 返回PeriodIndex类型列,不可直接 JSON 序列化,LeetCode 环境中必然失败。 - ✅ 正确做法:必须将 Period 转为字符串,确保列数据类型为
object(即 Python 字符串),才能被安全序列化。
✅ 推荐解决方案(简洁、兼容、无副作用):
import pandas as pd
def monthly_transactions(transactions: pd.DataFrame) -> pd.DataFrame:
# 确保 trans_date 是 datetime 类型(LeetCode 输入可能是 object 或 string)
transactions['trans_date'] = pd.to_datetime(transactions['trans_date'])
# 转为 'YYYY-MM' 字符串(非 Period!)
transactions['trans_date'] = transactions['trans_date'].dt.strftime('%Y-%m')
return transactions
? 为什么 strftime('%Y-%m') 更优?
- 输出为标准
str类型,零依赖、零序列化风险; - 语义清晰,结果与
to_period('M').astype(str)完全一致(如'2018-12'); - 性能略高,避免了 Period 对象构造与销毁开销。
? 替代方案(如需保留 Period 逻辑):
# 若坚持用 to_period,务必强制转 str
transactions['trans_date'] = transactions['trans_date'].dt.to_period('M').astype(str)
但注意:astype(str) 是必需步骤,缺之必报错。
? 额外提示:
- LeetCode 输入的
'trans_date'列未必是datetime64[ns]类型(常为object存储字符串),因此pd.to_datetime()调用不可或缺; - 不要尝试
.dt.to_period().dt.strftime()—— Period 没有.dt访问器; - 避免在原地修改列后立即用于复杂链式操作,优先保证类型纯净。
总结:在在线判题平台使用 Pandas 时,一切需输出的结果列,最终数据类型应限定为 int64、float64、bool 或 object(含字符串);Period、Interval、Timestamp 等带行为的类型极易引发序列化异常,应主动降级为基本类型。










