全文链接:https://tecdat.cn/?p=33550
原文出处:拓端数据部落公众号
什么是工夫序列?
工夫序列是一系列按工夫顺序排列的观测数据。数据序列能够是等距离的,具备特定频率,也能够是不规则距离的,比方电话通话记录。
在进行投资和交易钻研时,对于工夫序列数据及其操作要有业余的了解。本文将重点介绍如何应用 Python 和 Pandas 帮忙客户进行工夫序列剖析来剖析股票数据。
了解日期工夫和时间差
在咱们齐全了解 Python 中的工夫序列剖析之前,理解刹时、持续时间和时间段的差别十分重要。
类型 | 形容 | 例子 |
---|---|---|
日期(刹时) | 一年中的某一天 | 2019 年 9 月 30 日,2019 年 9 月 30 日 |
工夫(刹时) | 工夫上的单个点 | 6 小时,6.5 分钟,6.09 秒,6 毫秒 |
日期工夫(刹时) | 日期和工夫的组合 | 2019 年 9 月 30 日 06:00:00,2019 年 9 月 30 日上午 6:00 |
持续时间 | 两个刹时之间的差别 | 2 天,4 小时,10 秒 |
时间段 | 工夫的分组 | 2019 第 3 季度,一月 |
Python 的 Datetime 模块
datetime 模块提供了在简略和简单形式下进行日期和工夫操作的类。
创立刹时
日期、日期工夫和工夫都是独自的类,咱们能够通过多种形式创立它们,包含间接创立和通过字符串解析。
now = datetime.datetime.today()
today = datetime.date.today()
print(now)
print(today)
创立持续时间
timedeltas 示意工夫的持续时间。它们能够与工夫点相加或相减。
past = now - alldelta
print(type(future))
print(future)
print(type(past))
print(past)
拜访日期工夫属性
类和对象属性能够帮忙咱们拆散出咱们想要看到的信息。我列出了最常见的属性,但你能够在 datetime 模块的文档上找到详尽的列表。
类 / 对象 | 属性 | 形容 |
---|---|---|
共享类属性 | class.min | 可示意的最早日期、datetime、time |
class.max | 可示意的最晚日期、datetime、time | |
class.resolution | 两个日期、datetimes 或 times 之间的最小差值 | |
日期 / 日期工夫 | object.year | 返回年份 |
object.month | 返回月份(1 – 12) | |
object.day | 返回日期(1-32) | |
工夫 / 日期工夫 | object.hour | 返回小时(0-23) |
object.minute | 返回分钟(0-59) | |
object.second | 返回秒数(0-59) |
print(datetime.datetime.min)
print(datetime.datetime.max)
print(datetime1.microsecond)
在 Pandas 中创立工夫序列
让咱们获取由 Intrinio 开发者沙盒提供的苹果股票历史数据。
apple_price_history = pd.read_csv(f)
apple_price_history[['open', 'high', 'low', 'close', 'volume']].head()
让咱们查看数据框的数据类型或 dtypes,看看是否有任何日期工夫信息。
让咱们将数据框的 RangeIndex 更改为 DatetimeIndex。为了难看,咱们将展现如何应用 read_csv
用 DatetimeIndex 读取数据。
apptime64)
apple_price_history.dtypes
print(apple_price_history[['open', 'high', 'low', 'close']].head())
apple_price_history.index[0:10]
import numpy as np
import urllib.request
index_col='date',
usecols=['date',
'adj_open',
'adj_high',
'adj_low',
'adj_close',
'adj_volume'])
apple_price_history.columns = names
print(apple_price_history.head())
增加日期工夫字符串
通常,日期的格局可能是无奈解析的。咱们能够应用 dt.strftime
将字符串转换为日期。在创立 sp500 数据集 时,咱们应用了strptime
。
sp500.loc[:,'date'].apply(lambda x: datetime.strptime(x,'%Y-%m-%d'))
工夫序列抉择
按日、月或年抉择日期工夫
当初咱们能够应用索引和 loc
轻松抉择和切片日期。
apple_price_history.loc['2018-6-1']
应用日期工夫拜访器
dt 拜访用具有多个日期工夫属性和办法,能够利用于系列的日期工夫元素上,这些元素在 Series API 文档中能够找到。
属性 | 形容 |
---|---|
Series.dt.date | 返回蕴含 Python datetime.date 对象的 numpy 数组(即,没有时区信息的工夫戳的日期局部)。 |
Series.dt.time | 返回 datetime.time 的 numpy 数组。 |
Series.dt.timetz | 返回还蕴含时区信息的 datetime.time 的 numpy 数组。 |
Series.dt.year | 日期的年份。 |
Series.dt.month | 月份,其中一月为 1,十二月为 12。 |
Series.dt.day | 日期的天数。 |
Series.dt.hour | 工夫的小时。 |
Series.dt.minute | 工夫的分钟。 |
Series.dt.second | 工夫的秒数。 |
Series.dt.microsecond | 工夫的微秒数。 |
Series.dt.nanosecond | 工夫的纳秒数。 |
Series.dt.week | 年的星期序数。 |
Series.dt.weekofyear | 年的星期序数。 |
Series.dt.dayofweek | 星期几,星期一为 0,星期日为 6。 |
Series.dt.weekday | 星期几,星期一为 0,星期日为 6。 |
Series.dt.dayofyear | 年的第几天的序数。 |
Series.dt.quarter | 季度。 |
Series.dt.is_month_start | 示意日期是否为月的第一天。 |
Series.dt.is_month_end | 示意日期是否为月的最初一天。 |
Series.dt.is_quarter_start | 示意日期是否为季度的第一天。 |
Series.dt.is_quarter_end | 示意日期是否为季度的最初一天。 |
Series.dt.is_year_start | 示意日期是否为年的第一天。 |
Series.dt.is_year_end | 示意日期是否为年的最初一天。 |
Series.dt.is_leap_year | 示意日期是否为平年。 |
Series.dt.daysinmonth | 月份中的天数。 |
Series.dt.days_in_month | 月份中的天数。 |
Series.dt.tz | 返回时区(如果有)。 |
Series.dt.freq |
办法 | 形容 |
---|---|
Series.dt.to_period(self, args, *kwargs) | 将数据转换为特定频率的 PeriodArray/Index。 |
Series.dt.to_pydatetime(self) | 将数据返回为本机 Python datetime 对象的数组。 |
Series.dt.tz_localize(self, args, *kwargs) | 将时区非感知的 Datetime Array/Index 本地化为时区感知的 Datetime Array/Index。 |
Series.dt.tz_convert(self, args, *kwargs) | 将时区感知的 Datetime Array/Index 从一个时区转换为另一个时区。 |
Series.dt.normalize(self, args, *kwargs) | 将工夫转换为午夜。 |
Series.dt.strftime(self, args, *kwargs) | 应用指定的日期格局转换为索引。 |
Series.dt.round(self, args, *kwargs) | 对数据执行舍入操作,将其舍入到指定的频率。 |
Series.dt.floor(self, args, *kwargs) | 对数据执行 floor 操作,将其舍入到指定的频率。 |
Series.dt.ceil(self, args, *kwargs) | 对数据执行 ceil 操作,将其舍入到指定的频率。 |
Series.dt.month_name(self, args, *kwargs) | 返回具备指定区域设置的 DateTimeIndex 的月份名称。 |
Series.dt.day_name(self, args, *kwargs) | 返回具备指定区域设置的 DateTimeIndex 的星期几名称。 |
周期
print(df.dt.quarter)
print(df.dt.day_name())
DatetimeIndex 包含与 dt 拜访器大部分雷同的属性和办法。
apple_price_history.index.day_name()
频率抉择
当工夫序列是平均距离的时,能够在 Pandas 中与频率关联起来。
pandas.date_range 是一个函数,容许咱们创立一系列平均距离的日期。
dates = pd.date_range('2019-01-01', '2019-12-31', freq='D')
dates
除了指定开始或完结日期外,咱们能够用一个周期来代替,并调整频率。
hours = pd.date_range('2019-01-01', periods=24, freq='H')
print(hours)
pandas.DataFrame.asfreq 返回具备新频率的数据帧或序列。对于数据中缺失的时刻,将增加新行并用 NaN 填充,或者应用咱们指定的办法填充。通常须要提供偏移别名以取得所需的工夫频率。
别名
别名 | 形容 |
---|---|
B | 工作日频率 |
C | 定制的工作日频率 |
D | 日历日频率 |
W | 周频率 |
M | 月底频率 |
SM | 半月末频率(每月 15 日和月末) |
BM | 工作日月末频率 |
CBM | 定制的工作日月末频率 |
MS | 月初频率 |
SMS | 半月初频率(每月 1 日和 15 日) |
BMS | 工作日月初频率 |
CBMS | 定制的工作日月初频率 |
Q | 季末频率 |
BQ | 工作日季末频率 |
QS | 季初频率 |
BQS | 工作日季初频率 |
A, Y | 年末频率 |
BA, BY | 工作日年末频率 |
AS, YS | 年初频率 |
BAS, BYS | 工作日年初频率 |
BH | 工作小时频率 |
H | 小时频率 |
T, min | 分钟频率 |
S | 秒频率 |
L, ms | 毫秒 |
U, us | 微秒 |
N | 纳秒 |
print(apple_quarterly_history.head())
填充数据
pandas.Series.asfreq 容许咱们提供一个填充办法来替换 NaN 值。
print(apple_price_history['close'].asfreq('H', method='ffill').head())
从新采样:上采样和下采样
pandas.Dataframe.resample 返回一个从新取样对象,与 groupby 对象十分类似,能够在其上运行各种计算。
咱们常常须要升高(下采样)或减少(上采样)工夫序列数据的频率。如果咱们有每日或每月的销售数据,将其降采样为季度数据可能是有用的。或者,咱们可能心愿上采样咱们的数据以匹配另一个用于进行预测的系列的频率。上采样较少见,并且须要插值。
print(apple_quarterly_history.agg({'high':'max', 'low':'min'})[:5])
当初咱们能够应用咱们下面发现的所有属性和办法。
print(apple_price_history.index.day_name())
Index(['Friday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday',
'Monday', 'Tuesday', 'Wednesday', 'Friday',
...
'Wednesday', 'Thursday', 'Friday', 'Monday', 'Tuesday', 'Wednesday',
'Thursday', 'Friday', 'Monday', 'Tuesday'],
dtype='object', name='date', length=9789)
print(datetime.to_period('Q'))
datetime.to_period('Q').end_time
滚动窗口平滑和挪动均匀
pandas.DataFrame.rolling 容许咱们将数据拆分为聚合的窗口,并利用诸如均值或总和之类的函数。
在交易中的一个典型例子是应用 50 天和 200 天的挪动平均线来买入和卖出资产。
让咱们计算苹果公司的这些指标。请留神,在计算滚动均值之前,咱们须要有 50 天的数据。
apple_price_history_recent[['close', 'rolling_50', 'rolling_200']].plot(title='Apple vs. 50SMA & 200SMA', figsize=(32,18))
应用 Matplotlib 可视化工夫序列数据
Matplotlib 使咱们能够轻松地可视化 Pandas 工夫序列数据。Seaborn 增加了额定的选项,帮忙咱们使图表更加丑陋。咱们导入 matplotlib 和 seaborn 来尝试几个根本的例子。
折线图
sns.lineplot 绘制规范折线图。它的工作形式相似于咱们下面应用的 dataframe.plot。
ax=ax).set_title("Apple Stock Price History")
Text(0.5, 1.0, 'Apple Stock Price History')
箱线图 / 盒图
盒图可能帮忙咱们对数据进行分组和了解其散布。对于季节性数据来说往往十分有用。
sns.set(rc={'figure.figsize':(32, 18)})
sns.boxplot(data=apple_price_recent_history, x='quarter', y='close').s
在 Pandas 中剖析工夫序列数据
工夫序列分析方法能够分为两类:
- 频域办法
- 时域办法
频域办法剖析信号在频率带(如最初 100 个样本)上的变动水平。时域办法剖析信号在指定时间段(如前 100 秒)内的变动水平。
工夫序列趋势、季节性和周期性
工夫序列数据能够合成为四个组成部分:
- 趋势
- 季节性
- 周期性
- 噪声
并不是所有的工夫序列都具备趋势、季节性或周期性;而且必须有足够的数据反对存在季节性、周期性或趋势。
并不是所有的工夫序列必须出现趋势或模式,它们也可能齐全是随机的。
除了高频变动(如季节性和噪声)外,工夫序列数据通常还会出现突变的变异性。通过在不同时间尺度上进行滚动均匀能够很容易地可视化这些趋势。让咱们导入苹果公司的销售数据以钻研季节性和趋势。
趋势
趋势指的是工夫序列中存在回升或降落斜率的状况。亚马逊的销售增长就是回升趋势的一个例子。此外,趋势不肯定是线性的。趋势能够是确定性的,是工夫的函数,也能够是随机的。
季节性
季节性指的是一年外在固定工夫距离内察看到的显著反复模式,包含峰值和低谷。苹果公司的销售在第四季度达到峰值就是亚马逊支出中的一个季节性模式的例子。
周期性
周期性指的是在不规则工夫距离内察看到的显著反复模式,如商业周期。
让咱们剖析苹果公司的支出历史数据,看看是否进行合成。
import urllib
import pandas as pd
from scipy import stats
+ apple_revenue_history['fiscal_period'].str.upper()
slope, intercept, r_value, p_value, std_err = stats.linregress(apple_revenue_history.index,
工夫序列趋势图与趋势线
fig = plt.figure(figsize=(32,18))
ax1 = fig.add_subplot(1,1,1)
apple_revenue_history.plot(
工夫序列重叠图进行周期剖析
fig = plt.figure(figsize=(32,18))
ax1 = fig.add_subplot(1,1,1)
lsharey=True)
ax1.legend(legend)
合成工夫序列数据
statsmodel 能够将工夫序列统计分解为其组成部分。
apple_revenue_history.index = apple_revenue_history.index.to_timestamp(freq='Q')
# 加法合成
result_add = seasonal_decompose(apple_revenue_history['value'])
# 绘图
plt.rcParams.update({'figure.figsize': (32,18)})
工夫序列的平稳性
工夫序列与传统的分类和回归预测建模问题不同。工夫序列数据是有序的,并且须要平稳性能力进行有意义的摘要统计。
平稳性是工夫序列剖析中许多统计过程的假如,非安稳数据常常被转化为安稳数据。
平稳性有以下几种分类:
- 安稳过程 / 模型:安稳的察看序列。
- 趋势安稳:不出现趋势。
- 节令安稳:不出现季节性。
- 严格安稳:数学定义的安稳过程。
在一个安稳的工夫序列中,工夫序列的均值和标准差是恒定的。此外,没有季节性、周期性或其余与工夫相干的构造。通常首先查看工夫序列是否安稳,以更容易了解。
# 安稳序列
vol = .002
df1.plot(title='安稳序列')
df2.plot(title='非安稳序列:均值不恒定')
np.logspace(1,2,num=200, dtype=int))
df3.plot(title='非安稳序列:波动性不恒定')
df4[0] = df4[0] + df4['cyclical']
df4[0].plot(title='非安稳序列:周期性')
如何测验平稳性
咱们能够通过直观地查看上述图形来测试平稳性,就像之前所做的那样;将图形分成多个局部,查看均值、方差和相关性等摘要统计数据;或者应用更高级的办法,如增广迪基 - 富勒测验(Augmented Dickey-Fuller test)。
增广迪基 - 富勒测试用于测试是否存在单位根。如果工夫序列有单位根,则示意存在一些工夫相干构造,即工夫序列不是安稳的。
统计量越负值,工夫序列越有可能是安稳的。一般来说,如果 p 值 > 0.05,则数据有单位根,不是安稳的。让咱们应用 statsmodel 进行测验。
import pandas as pd
import numpy as np
from statsmodels.tsa.stattools import adfuller
print('Critial Values:')
print(f'{key}, {value:.2f}')
上述示例运行后打印出的测试统计值别离为 0.00(安稳)和 0.88(非安稳)。
如何解决非安稳工夫序列
如果工夫序列中存在显著的趋势和季节性,能够对这些组成部分进行建模,将它们从观测值中剔除,而后在残差上训练模型。
去趋势化
有多种办法能够从工夫序列中去除趋势成分。
- 减去最佳拟合直线
- 应用合成进行减法
- 应用滤波器进行减法
滤波器
应用 SciPy 进行最佳拟合直线
SciPy 的 detrend 函数能够通过减去最佳拟合直线来移除趋势。
detrend = signal.detrend(df[0].values)
plt.plot(detrend)
应用 StatsModels 进行合成
seasonal_decompose 函数返回一个带有季节性、趋势和残差属性的对象,咱们能够从系列值中减去它们。
from statsmodels.tsa.seasonal import seasonal_decompose
from dateutil.parser import parse
df[0].plot(figsize=(32,18))
df[0] = df[0] - decompose.trend
df[0].plot(figsize=(32,18))
最受欢迎的见解
1. 在 python 中应用 lstm 和 pytorch 进行工夫序列预测
2.python 中利用长短期记忆模型 lstm 进行工夫序列预测剖析
3.Python 用 RNN 循环神经网络:LSTM 长期记忆、GRU 门循环单元、回归和 ARIMA 对 COVID-19 新冠疫情新增人数工夫序列
4.Python TensorFlow 循环神经网络 RNN-LSTM 神经网络预测股票市场价格工夫序列和 MSE 评估准确性
5.r 语言 copulas 和金融工夫序列案例
6.R 语言用 RNN 循环神经网络、LSTM 长短期记忆网络实现工夫序列长期利率预测
7.Matlab 创立向量自回归(VAR)模型剖析消费者价格指数 (CPI) 和失业率工夫序列
8.r 语言 k -shape 工夫序列聚类办法对股票价格工夫序列聚类
9. R 语言联合新冠疫情 COVID-19 股票价格预测:ARIMA,KNN 和神经网络工夫序列剖析