You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

本地化Pandas Datetime序列存CSV时部分值变为-1的问题求助

问题描述

将本地化到America/Chicago时区的Pandas Datetime序列,尝试通过date_format='%s'参数保存为Unix时间戳格式的CSV时,出现部分Datetime值被保存为-1的异常;不同环境表现不同:

  • 在Databricks Runtime 10.4 LTS ML环境(Pandas 1.4/1.2.4、Python 3.8.1)中,保存后读取的CSV里前4行是正确时间戳,后6行均为-1
  • 在Jupyter环境(Pandas 1.2.4、Python 3.8.8)中执行相同代码,直接抛出ValueError: Invalid format string错误

复现代码如下:

import datetime
import pandas as pd

df_test = pd.DataFrame({
    "Batch ID": [6409713, 6409715, 6409719, 6409721, 6409723, 6409731, 6409733, 6409735, 6409739, 6409741],
    "      SCED Timestamp      ": [
        datetime.datetime(2022, 3, 13, 1, 40, 17, 999000),
        datetime.datetime(2022, 3, 13, 1, 45, 19),
        datetime.datetime(2022, 3, 13, 1, 50, 18),
        datetime.datetime(2022, 3, 13, 1, 55, 18, 999000),
        datetime.datetime(2022, 3, 13, 3, 0, 28),
        datetime.datetime(2022, 3, 13, 3, 5, 20),
        datetime.datetime(2022, 3, 13, 3, 10, 17, 999000),
        datetime.datetime(2022, 3, 13, 3, 15, 18),
        datetime.datetime(2022, 3, 13, 3, 20, 20),
        datetime.datetime(2022, 3, 13, 3, 25, 18, 999000)
    ],
    "Repeated Hour Flag": ['N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N'],
    "System Lamda": [27.3663, 26.2636, 28.441, 27.1946, 19.4144, 26.5737, 30.4865, 29.5245, 29.6784, 28.6156]
})

# 转换为带时区的Datetime索引
datetimes = pd.to_datetime(df_test['      SCED Timestamp      '])
datetimes = pd.DatetimeIndex(datetimes)
datetimes = datetimes.tz_localize('America/Chicago', ambiguous=(df_test['Repeated Hour Flag'] == 'N'))
datetimes.name = "Datetime"
df_test = df_test.set_index([datetimes])

# 保存为CSV时出现问题
df_test.index.to_series().to_csv('date_test.csv', date_format='%s')
# 读取后部分值为-1
print(pd.read_csv('date_test.csv'))
问题原因
  1. %s格式的兼容性问题:%s是Python标准库strftime的格式符,但Pandas官方并未将其纳入date_format参数的支持范围,其行为依赖底层系统的strftime实现,不同环境的底层库差异会导致报错或返回异常值(如-1)。
  2. 夏令时切换的影响:测试数据中的日期是2022年3月13日,当天是美国中部夏令时切换日(凌晨2点直接跳转为3点),后6个时间点处于切换后的时段,带时区的Datetime在与%s格式交互时,时区转换逻辑冲突导致异常。
  3. 旧版Pandas的bug:Pandas 1.2.x/1.4.x版本在处理带时区Datetime的%s格式时存在缺陷,要么无法识别格式抛出错误,要么错误返回-1。
解决方案

方法1:直接转换为Unix时间戳数值(推荐)

绕过date_format参数,先将带时区的Datetime索引转换为秒级Unix时间戳数值,再保存为CSV,这种方式不依赖底层strftime实现,完全避免时区和格式兼容问题:

# 将带时区的Datetime索引转换为秒级Unix时间戳
timestamp_series = df_test.index.astype('int64') // 10**9  # Pandas Datetime存储为纳秒,除以1e9转秒
timestamp_series.name = "Datetime"

# 保存为CSV
timestamp_series.to_csv('date_test.csv', header=True)

# 读取验证
print(pd.read_csv('date_test.csv'))

方法2:升级Pandas版本

升级到Pandas 1.5.x及以上版本,新版本会明确禁止在带时区Datetime上使用%s格式(直接抛出错误),避免出现静默生成-1的异常情况;但如果需要保存时间戳,方法1依然是更可靠的选择。

方法3:转换为UTC时区后再处理

如果需要保留Datetime格式的操作逻辑,可以先将时区转换为UTC,再使用date_format='%s'(仅适用于不需要保留原时区场景):

# 转换为UTC时区
utc_index = df_test.index.tz_convert('UTC')
# 保存为CSV
utc_index.to_series().to_csv('date_test.csv', date_format='%s')
# 读取验证
print(pd.read_csv('date_test.csv'))

内容的提问来源于stack exchange,提问作者Shahin Shirazi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 21:39:19