第2章:Python时间序列工具:Pandas时间序列基础、Statsmodels库简介、Matplotlib可视化基础
好,咱们直接进入正题。做时间序列分析,Python 的三件套你得先备齐:Pandas 管数据处理,Statsmodels 管统计建模,Matplotlib 管画图说话。这三样东西,我几乎每天都在用。
说实话,刚入行那会儿,我总觉得 Pandas 就是个 Excel 替代品。后来才发现,它在时间序列上的功力,远不止于此。今天咱们就把这三个工具的基础用法捋一遍。
2.1 Pandas 时间序列基础
Pandas 处理时间序列的核心,就是 DatetimeIndex。说白了,就是把普通的时间字符串,变成 Pandas 能识别的时间索引。
2.1.1 创建 DatetimeIndex
最常见的做法是用 pd.to_datetime()。我习惯把日期列先转成时间格式,再设为索引。
import pandas as pd
# 模拟一份销售数据
dates = ['2024-01-01', '2024-01-02', '2024-01-03', '2024-01-04']
sales = [120, 135, 110, 145]
df = pd.DataFrame({'date': dates, 'sales': sales})
df['date'] = pd.to_datetime(df['date'])
df.set_index('date', inplace=True)
print(df)
print(df.index)
输出结果里,索引会变成 DatetimeIndex(['2024-01-01', ...], dtype='datetime64[ns]', freq=None)。注意那个 freq=None,它表示 Pandas 还不知道你的数据频率。后面我们会手动指定。
pd.date_range() 直接生成日期范围。比如 pd.date_range(start='2024-01-01', periods=10, freq='D'),这样更干净。
2.1.2 时间索引的切片与筛选
有了 DatetimeIndex,切片就变得非常自然。你可以直接用字符串切片,Pandas 会自动解析。
# 选取 2024年1月2日 之后的数据
print(df['2024-01-02':])
# 选取整个 1月份 的数据(如果有跨月数据)
print(df['2024-01'])
嗯,这里要注意:切片时是包含起止日期的。我曾经在项目里因为没注意这个细节,多算了一天的数据,排查了半天才发现。
2.1.3 resample:重采样
重采样是时间序列分析里最常用的操作之一。它的作用,就是把高频数据降为低频(比如日转月),或者把低频数据升为高频(比如月转日)。
我个人习惯把 resample 理解为「按时间窗口分组聚合」。语法和 groupby 很像。
# 模拟每日数据,然后按月汇总
date_rng = pd.date_range(start='2024-01-01', end='2024-03-31', freq='D')
df_daily = pd.DataFrame(date_rng, columns=['date'])
df_daily['sales'] = np.random.randint(100, 200, size=len(date_rng))
df_daily.set_index('date', inplace=True)
# 按月重采样,求和
monthly_sum = df_daily.resample('M').sum()
print(monthly_sum)
常用的频率别名:'D' 代表天,'W' 代表周,'M' 代表月末,'MS' 代表月初,'Q' 代表季度末,'Y' 代表年末。
resample('M') 对日数据求和,结果发现每个月的最后一天被归到了下个月。后来才意识到,'M' 是「月末日历日」,而 'MS' 才是「月初」。如果你的数据是自然月,建议用 'MS'。
2.2 Statsmodels 库简介
Statsmodels 是 Python 里做统计建模的老牌库。它不像 scikit-learn 那样偏重机器学习,而是更注重统计推断和模型解释。对于时间序列,它提供了 ARIMA、SARIMAX、VAR 等经典模型。
你不需要一下子记住所有模型。先知道它怎么用就行。
2.2.1 安装与导入
# 安装
# pip install statsmodels
import statsmodels.api as sm
from statsmodels.tsa.stattools import adfuller, acf, pacf
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
我个人最常用的是 adfuller(单位根检验)和 plot_acf(自相关图)。这两个是判断数据是否平稳、以及确定模型阶数的关键工具。
2.2.2 一个简单的例子:ADF 检验
# 假设 df_daily 是我们的销售数据
result = adfuller(df_daily['sales'])
print(f'ADF Statistic: {result[0]}')
print(f'p-value: {result[1]}')
print(f'Critical Values: {result[4]}')
if result[1] < 0.05:
print('数据平稳,可以继续建模')
else:
print('数据不平稳,需要差分或变换')
p-value 小于 0.05,就说明数据是平稳的。如果大于 0.05,你就得考虑差分或者对数变换了。我在做股票收益率分析时,经常遇到不平稳的情况,这时候差分是第一步。
2.3 Matplotlib 可视化基础
做时间序列分析,画图是必须的。你想想看,一堆数字摆在那,你很难看出趋势、季节性和异常点。但一张图,什么都清楚了。
Matplotlib 是 Python 可视化的基石。虽然现在有很多高级库(比如 seaborn、plotly),但 Matplotlib 的灵活性和控制力,至今无人能敌。
2.3.1 快速画一条时间序列折线图
import matplotlib.pyplot as plt
plt.figure(figsize=(12, 5))
plt.plot(df_daily.index, df_daily['sales'], color='#2E86AB', linewidth=1.5)
plt.title('每日销售额趋势', fontsize=14)
plt.xlabel('日期')
plt.ylabel('销售额')
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
这里我习惯把 figsize 设得宽一些,因为时间序列通常跨度大,太窄的图看不出细节。颜色我常用 #2E86AB 这种蓝绿色,看着舒服。
2.3.2 多子图对比
有时候你需要同时看原始数据、差分后的数据、自相关图。这时候用 subplots 最方便。
fig, axes = plt.subplots(3, 1, figsize=(12, 10))
# 原始数据
axes[0].plot(df_daily.index, df_daily['sales'], color='#2E86AB')
axes[0].set_title('原始数据')
# 一阶差分
axes[1].plot(df_daily.index[1:], df_daily['sales'].diff().dropna(), color='#D64933')
axes[1].set_title('一阶差分')
# 自相关图
plot_acf(df_daily['sales'], lags=20, ax=axes[2])
axes[2].set_title('自相关函数 (ACF)')
plt.tight_layout()
plt.show()
1. 用 Pandas 把数据整理成带 DatetimeIndex 的格式
2. 用 Statsmodels 做平稳性检验和模型识别
3. 用 Matplotlib 把每一步的结果可视化出来,确保你的判断是合理的
好了,这一章的内容就这些。工具是基础,但别急着学太多。先把 Pandas 的 resample 和 Matplotlib 的折线图画熟练了,后面建模时才不会手忙脚乱。
下一章,咱们会正式进入时间序列的分解——把趋势、季节性和残差拆开来看。到时候你会发现,原来数据里藏着这么多故事。