Flask中使用to_dict('records')转换DataFrame报NaTType错误
问题原因及解决办法
核心原因
- pandas版本差异:Flask运行环境的pandas版本比Jupyter Notebook里的旧,旧版本pandas在执行
to_dict('records')时,对NaT(缺失的时间值)的处理存在bug,会触发timetuple转换报错;而新版本已经修复了这个问题,所以Notebook里正常。 - 序列化触发场景不同:Flask返回字典时,默认会自动调用JSON序列化来处理响应内容,这时候会尝试把
NaT对象转成可序列化的格式,而NaT本身不支持timetuple转换,导致报错;但在Notebook里只是打印字典,不会触发强制JSON序列化,所以看不到错误。
解决办法
- 统一pandas版本:查看Notebook里的pandas版本(执行
pd.__version__),然后把Flask环境的pandas升级到相同版本,比如用命令:pip install pandas==x.x.x(替换成你的版本号)。 - 提前处理NaT值:在转字典前,把DataFrame里的
NaT替换成None或者可序列化的字符串:# 替换所有NaT为None df = df.replace({pd.NaT: None}) # 或者针对时间列单独处理,转成ISO格式字符串或None df['time_column'] = df['time_column'].apply(lambda x: x.isoformat() if pd.notna(x) else None) # 再转字典 result = df.to_dict('records') - 自定义Flask JSON编码器:如果不想修改数据,可以在Flask app里配置自定义编码器,自动处理
NaT和时间类型:from flask import Flask, jsonify from flask.json import JSONEncoder import pandas as pd import datetime class CustomJSONEncoder(JSONEncoder): def default(self, obj): if isinstance(obj, pd.Timestamp): return obj.isoformat() elif isinstance(obj, pd.NaTType): return None elif isinstance(obj, datetime.datetime): return obj.isoformat() return super().default(obj) app = Flask(__name__) app.json_encoder = CustomJSONEncoder # 之后返回字典时直接用jsonify(result)即可
内容的提问来源于stack exchange,提问作者ahmad Abdallah
相关产品推荐
相关产品推荐

