【Python数据分析】时间序列数据分析,看这一篇就够了!
时间序列就是按照时间顺序排列的一组数据序列,在生活中很多领域,在各个方面,时间序列都是很重要的结构化数据类型。毕竟时间对于人类来说,是很重要的东西。
时间序列数据分析技术就是发现这组数据的变化规律并用于预测的统计技术。
Python标准库中已经包含了用于日期(date)、时间(time)、日历数据的数据类型,主要用于datetime(日期和时间)、time(指的是具体的时、分、秒)、calendar(日历)模块。
类型 | 说明 |
---|---|
date | 日期(年月日) |
time | 时间(时分秒) |
datetime | 日期和时间(包含上面两个) |
timedelta | 两个datetime的差值 |
tzinfo | 用于存储时区信息的基本类型 |
import datetime
date = datetime.date(2025,5,13)
print(date.year)
print(date.month)
print(date.day)
time = datetime.time(16,42,50)
print(time)
now = datetime.datetime.now()
print(now)
date1 = date + datetime.timedelta(120) # 加天数
print(date1)
birth = datetime.datetime(2005,2,7)
delta = now - birth # 注意这里只能是差值,不能相加
print(delta)
在数据分析中,字符串和datetime类数据需要进行转换,通过str方法可以直接将datetime类数据转换为字符串数据。
stamp = datetime.datetime(2005,5,3)
print(str(stamp))
如果需要将datetime类数据转换为特定格式的字符串数据,需要使用strftime方法。
daretime格式说明如下表:
# 转换成 四位年份/两位月份/两位日期
stamp = datetime.datetime(2005,5,3)
print(stamp.strftime('%Y/%m/%d')) #2005/05/03
Pandas中的基础时间序列种类是由时间戳索引的Series,在Pandas外部则表示为Python字符串或datetime对象。
基于Pandas,我们时间序列的构造就是以时间数据为索引的Series或者DataFrame,构造方法即为Series。
pdates = [datetime.datetime(2025,5,13),datetime.datetime(2025,5,18),datetime.datetime(2025,5,20)]
s = pd.Series(np.arange(3),index = pdates)
print(s)
2025-05-13 0
2025-05-18 1
2025-05-20 2
dtype: int64
与其他Series类似,不同索引的时间序列之间的算术运算在日期上会自动对齐。
和Pandas中使用索引的方法一样。
print(s[:2])
2025-05-13 0
2025-05-18 1
dtype: int64
也可以使用索引获取时间序列的切片
print(s['2025-5-13':'2025-5-18'])
2025-05-13 0
2025-05-18 1
dtype: int64
或者是使用其中的年、月、日分别来获取切片
# 使用年获取切片
print(s['2025')
# 使用月获取切片
print(s['2025-5'])
# 使用月和日获取切片
print(s['2025-05-18':'2025-05-20'])
2025-05-13 0
2025-05-18 1
2025-05-20 2
dtype: int64
2025-05-13 0
2025-05-18 1
2025-05-20 2
dtype: int64
2025-05-18 1
2025-05-20 2
dtype: int64
Pandas的通用时间序列是不规则的,也就是说时间序列的频率是不固定的。
但是我们经常会需要处理固定频率的场景,如每天每月等等,所以,Pandas也提供一套标准的时间序列频率和工具用于重新采样、推断频率及生成固定频率的数据范围。
使用pd.date_range
创建指定长度的DatetimeIndex索引。
index = pd.date_range('2020-12-25','2021-1-8')
print(index)
DatetimeIndex(['2020-12-25', '2020-12-26', '2020-12-27', '2020-12-28',
'2020-12-29', '2020-12-30', '2020-12-31', '2021-01-01',
'2021-01-02', '2021-01-03', '2021-01-04', '2021-01-05',
'2021-01-06', '2021-01-07', '2021-01-08'],
dtype='datetime64[ns]', freq='D')
如果不指定开始日期或者结束日期的其中之一,那么就需要指定一个长度,我们使用periods
来进行传递。
# 从start开始前进
index = pd.date_range(start = '2020-12-25',period = 10)
print(index)
# 从end开始倒退
index = pd.date_range(end = '2020-12-25',period = 10)
print(index)
DatetimeIndex(['2020-12-25', '2020-12-26', '2020-12-27', '2020-12-28',
'2020-12-29', '2020-12-30', '2020-12-31', '2021-01-01',
'2021-01-02', '2021-01-03'],
dtype='datetime64[ns]', freq='D')
DatetimeIndex(['2020-12-16', '2020-12-17', '2020-12-18', '2020-12-19',
'2020-12-20', '2020-12-21', '2020-12-22', '2020-12-23',
'2020-12-24', '2020-12-25'],
dtype='datetime64[ns]', freq='D')
时间序列的频率由基础频率和日期偏置(指的是缩写的全称)组成,可以通过freq
参数使用其他频率,基础时间序列频率见表:
类型 | 偏置类型 | 描述 |
---|---|---|
D | Day | 日历日的每天 |
B | BusinessDay | 工作日的每天 |
H | Hour | 每小时 |
T或min | Minute | 每分钟 |
S | Second | 每秒 |
M | MonthEnd | 每个月最后一个工作日 |
BM | BusinessMonthEnd | 工作日的月底日期 |
MS | MonthBegin | 工作日的月初日期 |
A-JAN | BusinessYearEnd | 每年指定月份的最后一个日历日 |
在类型前面可以添加整数,例如“2H”,指的是“每两个小时”
移位指的是将日期按时间向前或向后移动。Series和DataFrame都有一个shift方法用于简单地前向或后向移位,而不改变索引。
wdate = pd.Series(np.random.randn(4),index = pd.date_range('2019/1/1',periods=4,freq='W'))
print(wdate)
print(wdate.shift(2))
2019-01-06 0.713528
2019-01-13 -0.935406
2019-01-20 0.565824
2019-01-27 0.685361
Freq: W-SUN, dtype: float64
2019-01-06 NaN
2019-01-13 NaN
2019-01-20 0.713528
2019-01-27 -0.935406
这样就仅仅是直接删除了数据,不会修改索引。如果我们传入频率参数,就可以修改索引。
wdate = pd.Series(np.random.randn(4),index = pd.date_range('2019/1/1',periods=4,freq='W'))
print(wdate)
print(wdate.shift(2,freq = 'D'))
2019-01-08 0.627763
2019-01-15 1.510974
2019-01-22 2.215427
2019-01-29 0.696788
dtype: float64
时期表示的是时间区间,如数天,数月或数年等。
Period可以创建时期型的数据,传入字符串、整数或频率都可以。
w = pd.Period(2019,freq = 'A-DEC')
print(w)
print(w + 2)
可以通过Pandas中的例如date_range等方法创建日期范围。
wdate = pd.period_range('2019/1/1','2019/6/1',freq = 'M')
print(pd.Series(np.arange(6),index=wdate))
Period和PeriodIndex对象可以通过asfreq方法转换频率。
wdate = pd.period_range('2019/1/1','2019/6/1',freq = 'M')
print(wdate.asfreq('Y',how = 'start'))
使用to_period
可以将以时间戳作为索引的时间序列数据转换为以时期为索引的时间序列。
w = pd.date_range('2019/1/1','2019/6/1',freq = 'M')
y = pd.Serios(np.arange(5),index = w)
重采样是时间序列频率转换的过程。
高频率聚合到低频率称为降采样;低频率转换到高频率称为升采样。
Pandas中的resample
函数用于各种频率的转换工作。
参数 | 描述 |
---|---|
freq | 转换频率 |
axies=0 | 重采样的轴 |
closed = ‘right’ | 设置各时间段那端是闭合的 |
label = ‘right’ | 如何设置聚合值的标签 |
loffset = None | 设置时间偏移 |
kind = None | 聚合到时期,默认为时间序列的索引类型 |
convention | 升采样采用的约定,默认为end |
主要考虑closed和label参数。分别表示哪边区间是闭合,哪边是标记的。
主要是数据的插值,即对缺失值进行填充,填充方法于fillna类似。
在做时间序列分析时,要经常对时间序列做平稳性实验。
分别有以下三种:时序图检验、自相关图检验、构造统计量检验
通过绘制时间序列的折线图,观察数据的趋势和波动性。如果时间序列存在明显的趋势(如上升或下降)或周期性波动,则说明序列可能是非平稳的。
matplotlib
绘制时间序列图。
import matplotlib.pyplot as plt
# 示例代码
plt.plot(time_series)
plt.title("时序图")
plt.xlabel("时间")
plt.ylabel("值")
plt.show()
通过绘制自相关函数(ACF)图,观察时间序列的自相关性。如果序列的自相关系数随滞后时间迅速衰减到零,则序列可能是平稳的;如果自相关系数缓慢衰减或呈现周期性,则可能是非平稳的。
statsmodels
的 plot_acf
函数绘制自相关图。
from statsmodels.graphics.tsaplots import plot_acf
# 示例代码
plot_acf(time_series, lags=30)
plt.title("自相关图")
plt.show()
通过统计检验方法(如ADF检验、KPSS检验)判断时间序列的平稳性。ADF(Augmented Dickey-Fuller)检验是最常用的方法,其原假设是序列非平稳。如果检验的 p 值小于显著性水平(如 0.05),则可以拒绝原假设,认为序列是平稳的。
statsmodels
的 adfuller
函数进行 ADF 检验。
from statsmodels.tsa.stattools import adfuller
# 示例代码
result = adfuller(time_series)
print("ADF 检验统计量:", result[0])
print("p 值:", result[1])
print("临界值:", result[4])
if result[1] < 0.05:
print("序列是平稳的")
else:
print("序列是非平稳的")
的
adfuller` 函数进行 ADF 检验。from statsmodels.tsa.stattools import adfuller
# 示例代码
result = adfuller(time_series)
print("ADF 检验统计量:", result[0])
print("p 值:", result[1])
print("临界值:", result[4])
if result[1] < 0.05:
print("序列是平稳的")
else:
print("序列是非平稳的")
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有