pandas.dt用法

本文最后更新于 2025年8月3日 中午

一、 .dt 在不同场景的使用

1. Pandas Series (列)

这是 .dt 访问器的主要使用场景。

当一个 Series 的数据类型(dtype)是 datetime64[ns] 时,你可以使用 .dt 访问器来对 该列中的每一个元素 执行日期时间操作。这是一种向量化的操作,速度快,代码简洁。

  • 核心作用:对整列数据进行批量、向量化的日期时间处理。
  • 语法series.dt.属性series.dt.方法()

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import pandas as pd

# 创建一个包含日期时间的 Series
s = pd.Series(pd.to_datetime(['2023-01-15 08:30:00', '2024-05-20 18:00:00', '2025-11-30 23:59:59']))

# 使用 .dt 访问器
print("年份:")
print(s.dt.year)
print("-" * 20)

print("月份:")
print(s.dt.month_name())
print("-" * 20)

# 提取日期部分 (结果仍然是 Series)
print("仅日期:")
print(s.dt.date)
print("-" * 20)

# 判断是否是年底
print("是否是年底:")
print(s.dt.is_year_end)

2. 单个时间类型的数据 (Single Value)

单个时间对象,例如 Python 内置的 datetime.datetime 或 Pandas 的 Timestamp不能也无需 使用 .dt 访问器。你可以直接访问它的属性或调用它的方法。

  • 核心作用:直接获取单个日期时间对象的信息。
  • 语法timestamp_object.属性timestamp_object.方法()

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import pandas as pd
from datetime import datetime

# 获取一个 Pandas Timestamp 对象
ts = pd.Timestamp('2025-08-03 10:30:45')

# 直接访问属性
print(f"年份: {ts.year}")
print(f"月份: {ts.month}")
print(f"小时: {ts.hour}")
print("-" * 20)

# 直接调用方法
print(f"星期几的名称: {ts.day_name()}")
print(f"仅日期部分: {ts.date()}") # 注意这里是 .date() 方法
print("-" * 20)


# 对于 Python 原生的 datetime 对象也是一样
dt_native = datetime(2025, 8, 3, 10, 30, 45)
print(f"原生对象的年份: {dt_native.year}")
print(f"原生对象的日期部分: {dt_native.date()}") # 同样是 .date() 方法

# 错误尝试:在单个对象上使用 .dt 会报错
# ts.dt.year
# AttributeError: 'Timestamp' object has no attribute 'dt'

3. Pandas DataFrame (表)

DataFrame 是一个二维表格,由多个 Series 组成。因此,你 **不能直接对整个 DataFrame 使用 .dt**。你必须先选中那个包含日期时间数据的 特定列(它是一个 Series),然后再对该列使用 .dt 访问器。

  • 核心作用:DataFrame 是数据的容器。你需要先指定要操作的列。
  • 语法dataframe['列名'].dt.属性

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import pandas as pd

# 创建一个 DataFrame
df = pd.DataFrame({
'event': ['A', 'B', 'C'],
'timestamp': pd.to_datetime(['2023-01-15 08:30:00', '2024-05-20 18:00:00', '2025-11-30 23:59:59']),
'value': [100, 150, 200]
})

print("原始 DataFrame:")
print(df)
print("-" * 20)

# 从 'timestamp' 列中提取年份,并创建新列
df['year'] = df['timestamp'].dt.year

# 从 'timestamp' 列中提取星期,并创建新列
df['day_of_week'] = df['timestamp'].dt.day_name()

print("处理后的 DataFrame:")
print(df)
print("-" * 20)

总结对比

类型 是否使用 .dt 目的 示例
Pandas Series (必须使用) 对整列数据进行批量、向量化操作 s.dt.year
单个时间对象 (不能使用) 直接获取单个对象的值 ts.year
Pandas DataFrame 间接使用 先选择特定列(Series),再使用.dt df['col'].dt.year

记住这个关键点: .dt 是 Pandas Series 的专属工具,用于解决对一整列日期时间数据进行统一操作的需求。

二、 .dt的具体属性和方法

准备工作

首先,我们需要一个包含日期时间数据的 Pandas Series 来演示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import pandas as pd

# 创建一个示例 Series,数据类型为 datetime64[ns]
s = pd.Series(pd.to_datetime([
'2023-01-05 08:30:00',
'2024-03-15 12:00:00',
'2025-09-20 22:45:30',
'2025-12-31 23:59:59',
None # 包含一个缺失值用于演示
]))

print("示例 Series:")
print(s)
print("-" * 30)

1. 提取时间分量 (Accessing Components)

这些属性用于提取日期或时间的特定部分,返回一个与原 Series 等长的整数或浮点数 Series。

日期部分

  • .dt.date: 提取日期部分(年月日),返回一个包含 Python datetime.date 对象的 Series。
  • .dt.year: 提取年份。
  • .dt.month: 提取月份(1-12)。
  • .dt.day: 提取天数(1-31)。
  • .dt.day_of_year: 提取这是一年中的第几天(1-366)。
  • .dt.day_of_week.dt.weekday: 提取星期几(周一=0, 周日=6)。
  • .dt.quarter: 提取季度(1-4)。

代码示例 (日期)

1
2
3
4
5
6
print(f"年份:\n{s.dt.year}\n")
print(f"月份:\n{s.dt.month}\n")
print(f"天数:\n{s.dt.day}\n")
print(f"星期几 (周一=0):\n{s.dt.day_of_week}\n")
print(f"季度:\n{s.dt.quarter}\n")
print(f"一年中的第几天:\n{s.dt.day_of_year}\n")

时间部分

  • .dt.time: 提取时间部分(时分秒),返回一个包含 Python datetime.time 对象的 Series。
  • .dt.hour: 提取小时(0-23)。
  • .dt.minute: 提取分钟(0-59)。
  • .dt.second: 提取秒(0-59)。
  • .dt.microsecond: 提取微秒。
  • .dt.nanosecond: 提取纳秒。

代码示例 (时间)

1
2
3
print(f"小时:\n{s.dt.hour}\n")
print(f"分钟:\n{s.dt.minute}\n")
print(f"秒:\n{s.dt.second}\n")

2. 时间属性判断 (Boolean Properties)

这些属性返回一个布尔值的 Series,用于判断日期是否满足特定条件。

  • .dt.is_year_start: 是否为年初第一天。
  • .dt.is_year_end: 是否为年末最后一天。
  • .dt.is_quarter_start: 是否为季度初第一天。
  • .dt.is_quarter_end: 是否为季度末最后一天。
  • .dt.is_month_start: 是否为月初第一天。
  • .dt.is_month_end: 是否为月末最后一天。
  • .dt.is_leap_year: 是否为闰年。

代码示例 (判断)

1
2
3
print(f"是否为闰年:\n{s.dt.is_leap_year}\n")
print(f"是否为月末:\n{s.dt.is_month_end}\n")
print(f"是否为年末:\n{s.dt.is_year_end}\n")

3. 名称和格式化 (Names & Formatting)

这些方法用于获取日期的名称或将其格式化为字符串。

  • .dt.month_name(): 获取月份的全名(”January”, “February” …)。
  • .dt.day_name(): 获取星期的全名(”Monday”, “Tuesday” …)。
  • .dt.strftime(format_string): 将日期时间格式化为指定格式的字符串,规则与 Python 的 strftime 相同。

代码示例 (格式化)

1
2
3
4
5
6
print(f"月份名称:\n{s.dt.month_name()}\n")
print(f"星期名称:\n{s.dt.day_name()}\n")

# 格式化为 "年-月-日 星期"
formatted_str = s.dt.strftime('%Y-%m-%d %A')
print(f"自定义格式:\n{formatted_str}\n")

4. 时间周期和舍入 (Rounding & Period)

这些方法用于对时间进行舍入、取整或转换为时间周期。

  • .dt.normalize(): 将时间部分归一化为午夜(00:00:00),相当于提取日期。
  • .dt.round(freq): 将时间舍入到指定的频率(如 'H', 'T', 'S' 等)。
  • .dt.floor(freq): 向下舍入到指定频率。
  • .dt.ceil(freq): 向上舍入到指定频率。
  • .dt.to_period(freq): 将日期时间转换为固定频率的时间段(Period)类型。例如,转换为以月为单位的周期。

代码示例 (舍入和周期)

1
2
3
4
5
6
7
8
9
10
11
# 归一化到午夜
print(f"归一化 (仅保留日期):\n{s.dt.normalize()}\n")

# 舍入到最近的小时
print(f"舍入到小时:\n{s.dt.round('H')}\n")

# 向下舍入到天
print(f"向下舍入到天:\n{s.dt.floor('D')}\n")

# 转换为以月为单位的周期
print(f"转换为周期 (月):\n{s.dt.to_period('M')}\n")

5. 时区处理 (Timezone Handling)

如果你的数据涉及多个时区,这些方法非常重要。

  • .dt.tz: 获取或设置 Series 的时区。
  • .dt.tz_localize(tz): 为没有时区信息的 Series(tz-naive)设置一个时区。
  • .dt.tz_convert(tz): 将有时区信息的 Series(tz-aware)转换到另一个时区。

代码示例 (时区)

1
2
3
4
5
6
7
8
9
10
11
12
13
# 创建一个无时区的 Series
s_naive = pd.Series(pd.to_datetime(['2023-01-01 09:00:00']))

# 1. 本地化为东八区时间 (中国)
s_localized = s_naive.dt.tz_localize('Asia/Shanghai')
print(f"本地化后:\n{s_localized}\n")

# 2. 转换为纽约时间 (美国东部)
s_converted = s_localized.dt.tz_convert('America/New_York')
print(f"转换为纽约时间后:\n{s_converted}\n")

# 3. 查看时区信息
print(f"时区信息: {s_converted.dt.tz}")

总结

.dt 访问器是 Pandas 中处理时间序列数据的核心接口,它提供了丰富、高效且易于使用的方法和属性,能够满足绝大部分日期时间处理需求。掌握它的用法能极大提升数据分析和预处理的效率。


pandas.dt用法
https://blog.wyyy.dpdns.org/2025/pandas-dt用法/
作者
lwy
发布于
2025年8月3日
许可协议