strptime为何返回纳秒时间戳?Pandas异常问题咨询
问题分析与解答
简化代码
df.loc[df.loc['A'].notnull(), 'B'] = df.loc[df.loc['A'].notnull(), 'A'].map( lambda x: dt.datetime.strptime(x, '%m/%d/%Y') )
问题现象
问题现象:
该代码为列'B'填充了19位整数(推测为纳秒级Unix时间戳),而非预期的datetime或pandas Timestamp类型。
背景补充:数据帧来自MSSQL Server导出的CSV文件,文件中的日期格式无前置零,这本不应造成问题,但重新格式化文件后,列'B'如预期填充了时间戳。已找到简易解决方案,但无法找到文档解释strptime为何返回整数,且在控制台(或Jupyter)中无法复现该行为。
Q1:此现象的原因是什么?
核心原因是你使用的旧版本pandas(0.18)的 dtype 处理逻辑限制,再结合目标列'B'的初始数据类型导致的:
- 首先要明确:
dt.datetime.strptime返回的确实是Python datetime对象,不是整数——问题出在pandas的赋值环节。 - 如果你的DataFrame中列'B'的初始 dtype 是整数类型(比如读取CSV时,pandas因为B列存在空值或其他整数值,自动将其识别为int类型),在pandas 0.18版本中,当你尝试将datetime对象赋值给整数类型列时,它不会自动将列的 dtype 升级为
datetime64[ns],而是会把datetime对象强制转换为对应的纳秒级Unix时间戳整数(本质是把datetime对象转换成从1970-01-01 00:00:00 UTC开始的纳秒数)。 - 你在控制台/Jupyter无法复现,大概率是因为测试用的DataFrame里,列'B'的初始 dtype 是
object(而非整数),这时候赋值datetime对象就会保留原类型,不会触发强制转换。
Q2:MSSQL的字符串格式化是否可能导致该行为?
MSSQL导出的日期无前置零(比如1/5/2024而非01/05/2024)本身不会直接导致这个问题——strptime('%m/%d/%Y')完全可以解析单数字的月份和日期,这部分是没问题的。
但存在间接影响的可能:如果MSSQL导出的CSV中,列'B'原本存在一些整数值(比如占位用的0或空值被识别为整数),pandas读取时会将'B'列的 dtype 设为整数类型,这就为后续赋值时的强制类型转换埋下了伏笔。重新格式化文件后,可能改变了CSV的结构(比如B列初始全为空,pandas识别为object类型),所以赋值时就正常保留了datetime类型。
Q3:是否应直接采用解决方案无需深究原因?
分情况来看:
- 如果这是一次性的临时任务,且当前解决方案已经稳定可用,完全可以直接用,不用花时间深究——毕竟解决问题是第一优先级。
- 但如果这是长期维护的数据处理流程,建议还是搞清楚原因:这个问题暴露了旧版本pandas的类型处理陷阱,后续遇到类似的列赋值场景,很可能会重复踩坑。而且你可以针对性优化:比如在赋值前先显式将'B'列转为
object或datetime64[ns]类型(df['B'] = df['B'].astype('object')),或者如果条件允许,升级到更高版本的pandas(虽然Python2.7已停止支持,但pandas 0.25+对类型处理的逻辑更智能,会自动处理这类赋值时的 dtype 转换)。
内容的提问来源于stack exchange,提问作者user128029
相关产品推荐
相关产品推荐

