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

Pandas to_datetime格式异常:datetime64列转YYYY-MM格式问题

解决DataFrame日期列转YYYY-MM格式且保留datetime64类型的问题

嘿,这个问题我之前也踩过坑!你之所以转成YYYY-MM字符串后再转回datetime64达不到预期,核心原因是**datetime64类型本质上需要完整的年-月-日信息**,单纯的YYYY-MM字符串转回去时,Pandas会自动补01作为日,但其实我们完全不用绕字符串转换的弯路——直接对日期做「月份截断」操作就能搞定。

最优方案:用dt.floor('M')截断到当月第一天

这个方法会把任意日期直接调整为对应月份的第一天,既保留了datetime64类型,又能完美代表整个月份的时间维度,后续做分组、排序、时间运算都完全没问题。

示例代码:

import pandas as pd

# 模拟你的原始数据
df = pd.DataFrame({'Date': ['1988-01-01', '1988-02-15', '1988-03-20']})
# 先确保列是datetime64类型(如果原始数据已经是可以跳过这步)
df['Date'] = pd.to_datetime(df['Date'])

# 生成保留datetime64类型的年月列
df['YearMonth'] = df['Date'].dt.floor('M')

# 查看结果和类型
print(df['YearMonth'])
print(df['YearMonth'].dtype)  # 输出:datetime64[ns]

输出的YearMonth列值会是1988-01-01、1988-02-01、1988-03-01,虽然显示带日,但本质上代表的是整个月份,如果你需要在展示时变成YYYY-MM格式,只需要在输出时用dt.strftime('%Y-%m')即可:

print(df['YearMonth'].dt.strftime('%Y-%m'))  # 输出:1988-01、1988-02、1988-03

关于你之前尝试的补充

其实你转字符串再转回datetime的思路是可以走通的,只是可能操作时没注意细节:

# 把日期转成YYYY-MM字符串再转回datetime64
df['Date'] = pd.to_datetime(df['Date'].dt.strftime('%Y-%m'))

这样得到的结果和dt.floor('M')是一样的(都是当月第一天),但这种方法需要两次类型转换,效率不如直接用floor高,所以更推荐前者。

额外说明:如果接受Period类型

如果你不严格要求datetime64,可以用dt.to_period('M')直接生成年月周期类型,它的显示就是YYYY-MM,而且专门用于按年月聚合:

df['YearMonth_Period'] = df['Date'].dt.to_period('M')
print(df['YearMonth_Period'])  # 输出:1988-01、1988-02、1988-03
print(df['YearMonth_Period'].dtype)  # 输出:period[M]

但要注意这种类型不能直接和datetime64做运算,所以如果需要后续时间操作,还是datetime64的方案更稳妥。

内容的提问来源于stack exchange,提问作者Abin John Thomas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:38:31