Pandas 时间序列入门实战:从 datetime 转换、dt 访问器到重采样
2026/9/19 4:09:40 网站建设 项目流程

Pandas 时间序列入门实战:从 datetime 转换、dt 访问器到重采样

【免费下载链接】pandasFlexible and powerful data analysis / manipulation library for Python, providing labeled data structures similar to R data.frame objects, statistical functions, and much more项目地址: https://gitcode.com/gh_mirrors/pa/pandas

引言

本教程来自 pandas 官方入门系列的第 9 篇(doc/source/getting_started/intro_tutorials/09_timeseries.rst),以真实的空气质量监测数据(NO₂ 与 PM2.5)为主线,系统讲解 pandas 时间序列处理的三块核心能力:把文本日期转换为 datetime 对象并使用 dt 访问器提取时间属性、以 DatetimeIndex 作为索引进行切片与绘图、以及通过 resample 改变时间序列频率。读完本文,你将能独立完成"数据清洗 → 时间特征提取 → 按时间分组统计 → 频率重采样"的完整实战链路。

本文使用的数据为NO_2和 PM2.5 空气质量数据,来自 OpenAQ 平台并经 py-openaq 包下载。其中 air_quality_no2_long.csv 记录了巴黎(FR04014)、安特卫普(BETR801)、伦敦(London Westminster)三个测量站点的 NO₂ 小时浓度值(字段:city, country, date.utc, location, parameter, value, unit)。

准备工作:加载并理解数据

本教程的数据存储在仓库的 doc/data/air_quality_no2_long.csv 中。首先读取数据并做两件基础处理:将date.utc列重命名为datetime(便于语义理解),并查看数据概貌:

import pandas as pd import matplotlib.pyplot as plt air_quality = pd.read_csv("data/air_quality_no2_long.csv") air_quality = air_quality.rename(columns={"date.utc": "datetime"}) air_quality.head()

此时datetime列仍是纯文本字符串,尚不能进行提取年份、星期几等任何时间运算。我们还可以确认数据覆盖的站点:

air_quality.city.unique()

使用 pandas datetime 属性

将文本日期转换为 Timestamp 对象

通过pd.to_datetime函数,pandas 会解析字符串并将其转换为 datetime 对象(示例中的时区格式解析结果为datetime64[us, UTC])。在 pandas 中,这类与标准库datetime.datetime相似的对象被称为pandas.Timestamp

air_quality["datetime"] = pd.to_datetime(air_quality["datetime"]) air_quality["datetime"]

从源码看,to_datetimepandas中一个带多重重载的转换入口(pandas/core/tools/datetimes.py),它支持标量、Series、列表/元组/Index/类数组等多种输入形态,并暴露了丰富的参数:

参数默认值作用
errors"raise"解析失败时的行为,可选"raise""coerce"(转为NaT)、"ignore"
dayfirst/yearfirstFalse控制日期中日月年的解析顺序
utcFalse是否按 UTC 时区返回
formatNone指定 strftime 格式模板,可大幅加速解析
unitNone数值输入的时间单位(如"s""ms""ns"
origin"unix"数值时间戳的参考原点
cacheTrue是否缓存唯一值以加速重复解析

提示:读文件时直接转换。很多数据集都含有日期列,pandas 的输入函数(如pd.read_csvpd.read_json)支持通过parse_dates参数在读取阶段就把指定列转换为Timestamp,无需事后二次处理:

pd.read_csv("data/air_quality_no2_long.csv", parse_dates=["datetime"])

Timestamp 带来的计算能力

为什么Timestamp对象有价值?因为它让日期信息可计算、可比较。例如获取时间序列的起止时间:

air_quality["datetime"].min(), air_quality["datetime"].max()

进一步可以算出整个时间序列的时间跨度。相减的结果是一个pandas.Timedelta对象——类似于标准库的datetime.timedelta,用于表示时间持续长度:

air_quality["datetime"].max() - air_quality["datetime"].min()

pandas 支持的各类时间概念(时间点、时间间隔、周期等)在用户指南的 time related concepts 章节中有系统介绍。

用 dt 访问器提取时间属性

基于Timestamp对象,pandas 提供了大量时间相关属性(如monthyearquarter等),全部通过dt访问器获取。例如新增一列仅含测量月份:

air_quality["month"] = air_quality["datetime"].dt.month air_quality.head()

dt访问器在源码中的实现类是CombinedDatetimelikeProperties(pandas/core/indexes/accessors.py),它组合了DatetimePropertiesTimedeltaPropertiesPeriodProperties三个能力集合,因此同一个访问器既能服务 datetime64 数据,也能服务 timedelta64 与 period 数据。可用的时间/日期组件属性完整对照表见用户指南的 time and date components 章节,dt访问器的更多细节见入门教程的 dt accessor 小节对应扩展(basics.dt_accessors)。

按星期与站点分组求均值(split-apply-combine)

沿用入门系列第 6 篇(06_calculate_statistics.rst)讲过的 split-apply-combine 模式:要计算每个星期几 × 每个站点的 NO₂ 平均浓度,只需用datetime属性的day_of_week(Monday=0,Sunday=6,同样经dt访问器取用)与location一起作为分组键:

air_quality.groupby( [air_quality["datetime"].dt.day_of_week, "location"])["value"].mean()
由于本教程使用的时间序列非常短,上述分析结果**不具备长期代表性**,仅用于演示方法。

绘制一天中的小时浓度模式

类似地,计算每个小时的平均 NO₂ 并绘制柱状图,即可观察所有站点共同的一天内污染变化规律:

fig, axs = plt.subplots(figsize=(12, 4)) air_quality.groupby(air_quality["datetime"].dt.hour)["value"].mean().plot( kind='bar', rot=0, ax=axs ) plt.xlabel("Hour of the day"); # custom x label using Matplotlib plt.ylabel("$NO_2 (µg/m^3)$");

这里再次用到dt.hour属性,配合groupby实现按小时的聚合。

Datetime 作为索引

入门系列第 7 篇(07_reshape_table_layout.rst)介绍了pivot:把每个测量站点变成独立的一列,从而将表格重塑:

no_2 = air_quality.pivot(index="datetime", columns="location", values="value") no_2.head()
透视之后,datetime 信息自动成为了表格的索引。一般而言,把某一列设为索引可以用 `set_index` 函数完成。

拥有 datetime 索引(即DatetimeIndex)后,可以解锁强大的功能:不再需要dt访问器,时间属性直接挂在索引上:

no_2.index.year, no_2.index.day_of_week

DatetimeIndex在源码中定义为"不可变的 ndarray-like datetime64 数据"(pandas/core/indexes/datetimes.py),内部以 int64 存储、可装箱为携带元数据的Timestamp对象。其优势还包括便捷的时间段子集选取,以及自适应的绘图时间刻度。

用字符串切片选取时间段

例如绘制 5 月 20 日至 5 月 21 日各站点的 NO₂ 变化:直接传入可解析为 datetime 的字符串即可对DatetimeIndex完成子集选取:

no_2["2019-05-20":"2019-05-21"].plot();

DatetimeIndex与字符串切片索引的更多细节见用户指南的 time series indexing 章节。

将时间序列重采样到其他频率

resample:按目标频率聚合

resample是处理带 datetime 索引时间序列时非常强大的方法,例如把小时级数据聚合为每个站点的月度最大值

monthly_max = no_2.resample("MS").max() monthly_max

resample的用法与groupby类似:

  • 它通过一个字符串(如"M""5H"等)定义目标频率,进行基于时间的分组
  • 它需要一个聚合函数(如meanmax等)。

在源码中,resample返回的Resampler类被定义为"用于重采样 datetimelike 数据的、类似 groupby 的操作"(pandas/core/resample.py),支持aggregatetransformapply等方法——这正是它和groupby在用法上高度一致的原因。

重采样后,时间序列的频率会记录在freq属性上:

monthly_max.index.freq

频率别名(offset alias)的完整对照表见用户指南的 offset aliases 章节。

重采样 + 绘图:日平均 NO₂

再比如绘制每个站点的日均NO₂ 值,用"D"作为目标频率、mean作为聚合函数,并直接绘图:

no_2.resample("D").mean().plot(style="-o", figsize=(10, 5));

重采样的更多高级能力(自定义聚合、asfreqohlc等)见用户指南的 resampling 章节。

核心要点回顾

  • 有效日期字符串可通过to_datetime函数转换,也可以在read_csvread_json等读取函数中通过parse_dates参数一次性完成;
  • pandas 中的 datetime 对象支持计算、逻辑运算,并可借助dt访问器获取各种日期相关属性;
  • DatetimeIndex内建了这些日期相关属性,并支持便捷的字符串切片选取;
  • resample是改变时间序列频率的强大方法,行为类似groupby

关于时间序列的完整全景(时间点、间隔、周期、时区、频率转换等),参见用户指南的时间序列与日期功能章节。

【免费下载链接】pandasFlexible and powerful data analysis / manipulation library for Python, providing labeled data structures similar to R data.frame objects, statistical functions, and much more项目地址: https://gitcode.com/gh_mirrors/pa/pandas

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询