商城首页欢迎来到中国正版软件门户

您的位置:首页 >Python如何提取日期列中的年和月_通过dt访问器获取year与month属性

Python如何提取日期列中的年和月_通过dt访问器获取year与month属性

  发布于2026-04-28 阅读(0)

扫一扫,手机访问

Python如何提取日期列中的年和月?通过dt访问器获取year与month属性

Python如何提取日期列中的年和月_通过dt访问器获取year与month属性

为什么直接用 df['date'].year 会报 AttributeError?

很多朋友在提取日期信息时,会下意识地直接调用 df['date'].year,结果迎面就是一个 AttributeError。问题出在哪?其实,Series 对象本身并没有 year 这个属性。只有那些已经被明确转换为 datetime64 类型的 Series,才能通过专门的 .dt 访问器来获取年、月、日等时间属性。如果你的日期列还是字符串或者 object 类型,直接调用 .dt.year,系统就会抛出那句经典的错误提示:AttributeError: Can only use .dt accessor with datetimelike values

所以,正确的操作顺序应该是:

立即学习“Python免费学习笔记(深入)”;

  • 先看类型:用 df['date'].dtype 看一眼,只要不是 datetime64[ns],就别想直接用 .dt
  • 强制转换:老老实实先做转换:df['date'] = pd.to_datetime(df['date'])。默认情况下,pandas 会尽力解析,遇到实在看不懂的值,会设为 NaT(Not a Time)。
  • 处理异常:如果数据里混着像 "2023-13-01" 这种不合法的日期,建议加上参数 errors='coerce',让 pandas 安静地把它们变成 NaT,而不是直接报错中断整个流程。

如何安全提取 year 和 month 并避免 NaN 引发的类型问题?

成功转换后,用 .dt.year.dt.month 提取似乎很简单,但这里有个暗坑:它们返回的是 Int64 类型,这是一种支持 NaN 的整数类型。当你兴冲冲地想把结果拿去拼接字符串或做计算时,NaN 可能会带来意想不到的兼容性问题。尤其要注意,.dt.month 对于正常日期返回 1 到 12,但对于 NaT,它返回的是 NaN,而不是 0。

因此,提取之后不能掉以轻心:

立即学习“Python免费学习笔记(深入)”;

  • 检查缺失:先看一眼有多少缺失值:df['date'].dt.year.isna().sum(),做到心中有数。
  • 谨慎填充:如果需要填充,可以用 .fillna(0).astype(int)。但要特别注意业务逻辑——把月份填成 0 通常没有意义。很多时候,保留 NaN 或者直接过滤掉异常行是更稳妥的选择。
  • 拼接字符串的陷阱:如果想生成“年-月”格式的字符串(比如“2023-05”),千万别直接用 df['date'].dt.year.astype(str) + '-' + df['date'].dt.month.astype(str)。因为一旦遇到 NaN,转成字符串就成了 "nan",结果会变成“2023-nan”。有更优雅的方法:df['date'].dt.to_period('M').astype(str)

dt.to_period('M') 比手动拼 year/month 更可靠吗?

答案是肯定的。手动拼接年份和月份,看似直接,实则麻烦不少:你得操心月份是不是单数要补零(避免出现“2023-5”而不是“2023-05”),还得处理 NaT 带来的字符串污染问题。而 .dt.to_period('M') 这个方法,可以说是为生成年月标识量身定做的。它返回一个 PeriodIndex,格式天生就是归一化的、不可变的,并且支持高效的向量化运算。NaT 在这里也会被自动转为 NaT,不会污染你的字符串结果。

具体可以这么用:

立即学习“Python免费学习笔记(深入)”;

  • 首选方法:生成年月列,直接用 df['ym'] = df['date'].dt.to_period('M')
  • 转为字符串:需要显示时,调用 .astype(str),结果保证是标准的 "YYYY-MM" 格式。
  • 分组统计:后续如果要按年月分组聚合,df.groupby('ym') 比用两个独立的整数列更简洁,语义也更清晰。
  • 注意限制:当然,Period 类型不能直接进行数学运算。如果你需要计算月份差,得先转回时间戳:(p2.to_timestamp() - p1.to_timestamp()) / np.timedelta64(1, 'M')

从字符串列提取年月时,format 参数能提升性能吗?

不仅能,而且提升非常明显。当你的日期字符串格式统一且已知时(比如全是 "%Y/%m/%d"),在调用 pd.to_datetime() 时传入 format 参数,pandas 就可以跳过耗时的格式自动推断过程。对于百万行级别的数据,这个操作带来的速度提升可能达到 5 到 10 倍。

性能优化的实操建议如下:

立即学习“Python免费学习笔记(深入)”;

  • 确认格式:确保格式统一后,使用 pd.to_datetime(df['date'], format='%Y-%m-%d')
  • 错误处理:指定格式后,一旦遇到不匹配的字符串,pandas 会直接报 ValueError。初次尝试时,建议加上 errors='coerce' 来探查数据质量,看看有多少行无法解析。
  • 常见格式符号:记住几个常用的:%Y(四位年份)、%y(两位年份)、%m(01-12月)、%B(英文全称月份)、%b(英文缩写月份)。
  • 格式混杂怎么办:如果数据源格式不纯,比如混着“2023-05-01”和“05/01/2023”,那就别硬套 format 了。老老实实用默认解析,并配合 errors='coerce' 来处理,更为稳妥。

话说回来,实际工作中最容易踩坑的,往往不是这些明面上的规则,而是数据本身埋的“雷”。比如原始列里藏着看不见的空格、特殊字符,或者混合了字符串和浮点数时间戳。这些问题不会立刻导致程序崩溃,但可能会让 .dt.year 默默地返回一整列 NaN,或者产生难以察觉的数据截断。所以,动手处理前,养成好习惯:用 df['date'].head(10).apply(type) 看看类型是否纯粹,再用 df['date'].str.strip().head() 快速检查一下有没有隐藏字符。磨刀不误砍柴工,这一步探查能省去后面大量的调试时间。

本文转载于:https://www.php.cn/faq/2382678.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注