您的位置:首页 >Python如何提取日期列中的年和月_通过dt访问器获取year与month属性
发布于2026-04-28 阅读(0)
扫一扫,手机访问

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,而不是直接报错中断整个流程。成功转换后,用 .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 或者直接过滤掉异常行是更稳妥的选择。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')。ValueError。初次尝试时,建议加上 errors='coerce' 来探查数据质量,看看有多少行无法解析。%Y(四位年份)、%y(两位年份)、%m(01-12月)、%B(英文全称月份)、%b(英文缩写月份)。format 了。老老实实用默认解析,并配合 errors='coerce' 来处理,更为稳妥。话说回来,实际工作中最容易踩坑的,往往不是这些明面上的规则,而是数据本身埋的“雷”。比如原始列里藏着看不见的空格、特殊字符,或者混合了字符串和浮点数时间戳。这些问题不会立刻导致程序崩溃,但可能会让 .dt.year 默默地返回一整列 NaN,或者产生难以察觉的数据截断。所以,动手处理前,养成好习惯:用 df['date'].head(10).apply(type) 看看类型是否纯粹,再用 df['date'].str.strip().head() 快速检查一下有没有隐藏字符。磨刀不误砍柴工,这一步探查能省去后面大量的调试时间。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
9