当前位置:首页>python>Python时间序列分析(一)

Python时间序列分析(一)

  • 2026-10-11 08:28:44
Python时间序列分析(一)
本文适用于零基础的Python学习的同学(比如我),小编是深度R用户,但是近期尝试了positron来编写代码,简直像开启了新世界的大门,R和Python无缝切换,真的很方便。所以慢慢也就开始上手学习Python。这节内容介绍时间序列分析。

1. 时间序列介绍 

时间序列是指按固定时间间隔记录的一系列观测数据。根据观测频率的不同,时间序列通常可以是每小时、每天、每周、每月、每季度和每年。有时,也可能出现秒级和分钟级的时间序列,例如每分钟的点击次数和用户访问次数等。

2. 如何在Python中导入时间序列数据 

时间序列数据通常以 .csv 文件或其他电子表格格式存储,包含两列:日期和测量值。 我们使用 pandas 包中的 read_csv() 函数将时间序列数据集(一个关于澳大利亚药品销售的 csv 文件)读取为 pandas 数据框。添加 parse_dates=[‘date’] 参数会将日期列解析为日期字段。

# 从dateutil包中导入parse函数,可以把把字符串日期(如 "2024-01-01")转换成日期时间格式from dateutil.parser import parse# 导入 matplotlib 主库,并命名为 mpl,matplotlib 是 Python 最常用的绘图库,mpl 常用于设置全局参数、颜色、字体等import matplotlib as mpl# 导入 pyplot 模块,并简写为 plt,pyplot类似R里面的plot()系统,用来画折线图、柱状图、散点图等import matplotlib.pyplot as plt# 导入seaborn,并简写为sns,seaborn基于matplotlib,画图更美观import seaborn as sns# 导入numpy,numpy用于数值计算、矩阵运算,类似R里面的向量/矩阵基础库import numpy as np# pandas 是处理表格数据最重要的库,类似 R 的 data.frame + dplyr + readr 综合体import pandas as pd# 设置matplotlib全局绘图参数# 'figure.figsize': (10,7)plt.rcParams.update({'figure.figsize': (10,7), 'figure.dpi': 120})# 读取当前数据,parse_dates=['date']表示把这一列自动识别为日期格式# 数据来源:https://raw.githubusercontent.com/selva86/datasets/master/a10.csvdf = pd.read_csv('project_1.csv', parse_dates=['date'])# 查看数据前5行df.head()
date
value
0
1991-07-01
3.526591
1
1991-08-01
3.180891
2
1991-09-01
3.252221
3
1991-10-01
3.611003
4
1991-11-01
3.565869
3. 什么是面板数据 (panel data)

面板数据也是基于时间的数据集。区别在于,除了时间序列之外,它还包含一个或多个在同意时间段内测量的相关变量。 通常情况下,面板数据中的列包含有助于预测Y的解释变量,前提是这些列在未来的预测期内可用。

# 面板数据示例# 数据来源: https://raw.githubusercontent.com/selva86/datasets/master/MarketArrivals.csv# 导入数据df = pd.read_csv('MarketArrivals.csv')# 从原始数据中筛选market列等于MUMBAI的行df = df.loc[df.market=='MUMBAI', :]df.head()
market
month
year
quantity
priceMin
priceMax
priceMod
state
city
date
6654
MUMBAI
January
2004
267100
719
971
849
MS
MUMBAI
January-2004
6655
MUMBAI
January
2005
275845
261
513
387
MS
MUMBAI
January-2005
6656
MUMBAI
January
2006
228000
315
488
402
MS
MUMBAI
January-2006
6657
MUMBAI
January
2007
205200
866
1136
997
MS
MUMBAI
January-2007
6658
MUMBAI
January
2008
267550
348
550
448
MS
MUMBAI
January-2008
4. 时间序列可视化
使用matplotlib可视化该序列。
# 加载库import matplotlib.pyplot as plt# 数据来源:https://raw.githubusercontent.com/selva86/datasets/master/a10.csv# 导入数据df = pd.read_csv('project_1.csv', parse_dates=['date'])# 可视化# 定义一个函数plot_df用于快速绘图def plot_df(df, x, y, title = "", xlabel = 'Date', ylabel = 'Value', dpi = 300) :    # 新建画布    plt.figure(figsize = (16,8), dpi = dpi)    # 绘制折线图,线条颜色为红色    plt.plot(x, y, color = 'tab:red')    # 获取当前坐标轴对象    plt.gca() .set(title = title, xlabel = xlabel, ylabel = ylabel)    # 显示图片    plt.show()# 调用plot_df函数绘图plot_df(df, x = df.index, y = df.value,         title = 'Monthly anti-diabetic drug sales in Australia from 1992 to 2008')
时间序列的季节性图 (Seasonal Plot of a Time Series),如下所示:
# 数据来源:https://raw.githubusercontent.com/selva86/datasets/master/a10.csv# 导入数据df = pd.read_csv('project_1.csv', parse_dates=["date"])# 重置行索引df.reset_index(inplace=True)# 准备数据df['year'] = [d.year for d in df.date]              # 取出date列,提取年份,逐个历遍每个日期df['month'] = [d.strftime('%b') for d in df.date]   # 提取月份years = df['year'].unique()                         # 提取year列中的所有唯一年份# 准备颜色# 设置随机种子数np.random.seed(100)# 随机选择颜色,replace=False表示不重复抽取颜色mycolors = np.random.choice(list(mpl.colors.XKCD_COLORS.keys()), len(years), replace=False)# 绘图plt.figure(figsize=(16,12), dpi= 80)for i, y in enumerate(years):    if i > 0:                plt.plot('month', 'value', data=df.loc[df.year==y, :], color=mycolors[i], label=y)        plt.text(df.loc[df.year==y, :].shape[0]-.9, df.loc[df.year==y, 'value'][-1:].values[0], y, fontsize=12, color=mycolors[i])# 修饰图plt.gca().set(xlim=(-0.3, 11), ylim=(2, 30), ylabel='$Drug Sales$', xlabel='$Month$')plt.yticks(fontsize=12, alpha=.7)plt.title("Seasonal Plot of Drug Sales Time Series", fontsize=20)plt.show()

从上图可以看到,每年2月,药品销量都会大幅下降,三月又会回升,四月再次下降,如此循环往复。显然,这种模式每年都会出现。

然而,随着时间的推移,药品总销售额呈上升趋势。我们可以通过绘制年度箱线图来直观地展示这一趋势及其逐年变化情况。同样,可以通过绘制月度箱线图来可视化月度分布情况。

# 数据来源:https://raw.githubusercontent.com/selva86/datasets/master/a10.csv# 导入数据df = pd.read_csv('project_1.csv', parse_dates=['date'], index_col='date')# 重置行索引df.reset_index(inplace=True)# 准备数据df['year'] = [d.year for d in df.date]df['month'] = [d.strftime('%b') for d in df.date]years = df['year'].unique()# 绘图fig, axes = plt.subplots(1, 2, figsize=(20,7), dpi= 80)sns.boxplot(x='year', y='value', data=df, ax=axes[0], palette='Set3')sns.boxplot(x='month', y='value', data=df.loc[~df.year.isin([1991, 2008]), :], ax = axes[1], palette = 'Pastel1')# 设置标题axes[0].set_title('Year-wise Box Plot\n(The Trend)', fontsize=18); axes[1].set_title('Month-wise Box Plot\n(The Seasonality)', fontsize=18)plt.show()
箱线图清晰地展示了分别按照年份和月份划分的分布情况。此外,从按月划分的箱线图可以看出,12月和1月的药品销量明显较高,这可能与节假日折扣有关。

5. 时间序列中的模式 (Patterns in a time series)

任何时间序列都可以分解为以下几个组成部分: 基准水平 + 趋势 + 季节性 + 误差。当时间序列中出现递增或递减的斜率时,即可观察到趋势。而当由于季节性因素导致在固定时间间隔内出现明显的重复模式时,即可观察到季节性。这种模式可能与一年中的月份、月份中的日期、星期几甚至一天中的时间有关。

然而,并非所有时间序列都必须具有趋势和/或季节性。一个时间序列可能没有明显的趋势,但具有季节性。反之亦然。因此,可以将时间序列想象成趋势、季节性和误差项的组合。

# 数据来源如下:# https://raw.githubusercontent.com/selva86/datasets/master/guinearice.csv# https://raw.githubusercontent.com/selva86/datasets/master/sunspotarea.csv# https://raw.githubusercontent.com/selva86/datasets/master/AirPassengers.csvfig, axes = plt.subplots(1,3, figsize=(20,4), dpi=100)pd.read_csv('guinearice.csv', parse_dates=['date'], index_col='date').plot(title='Trend Only', legend=False, ax=axes[0])pd.read_csv('sunspotarea.csv', parse_dates=['date'], index_col='date').plot(title='Seasonality Only', legend=False, ax=axes[1])pd.read_csv('AirPassengers.csv', parse_dates=['date'], index_col='date').plot(title='Trend and Seasonality', legend=False, ax=axes[2])

另一个需要考虑的方面是周期性行为。当序列的涨跌模式并非按照固定的日历周期发生时,就会出现周期性行为。需要注意的是,不要将“周期性”效应与“季节性”效应混淆。

那么,如何区分“周期性”模式和“季节性”模式呢?

如果这些模式并非基于固定的日历频率,那么它就是周期性的。因为与季节性不同,周期性影响通常受到商业和其他社会经济因素的影响。

上述是第一节时间序列分析的学习内容,希望能够对大家有所帮助。
参考来源:https://machinelearningplus.com/time-series/time-series-analysis-python/#timeseriesanalysisnotebook

最新文章

随机文章