【火炉炼AI】机器学习043-pandas操作时间序列数据

619 阅读5分钟

【火炉炼AI】机器学习043-pandas操作时间序列数据

(本文所使用的Python库和版本号: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 )

时间序列数据分析是机器学习领域中的一个重要领域,时间序列数据是随着时间变化而不断变化的数据,最典型的一个例子就是股价数据,随着日期的不同而不同,还有一年四季的温度变化,台风运行轨迹等等领域。这个领域的一个重要点是收集到的样本数据在时间是相关的,我们不能像以前那样打乱样本数据之间的顺序,故而这各领域需要特别的研究方式。


1. 准备时间序列数据

本章用到的时间序列数据来源于文件data_timeseries.txt,这个文件中第一列是年份,从1940到2015,第二列是月份,第三列和第四列是数据。

1.1 数据转换为时间序列格式

我们可以将第一列和第二列合并,然后在用一个函数将合并后的字符串转换为Date类型,但是此处的数据很有规律性,时间上没有遗漏,故而我们可以借助pandas的date_range()函数来构建时间序列,并将该时间序列作为DataFrame数据集的index

第一步:用pandas加载数据集

# 加载数据集
data_path='E:\PyProjects\DataSet\FireAI/data_timeseries.txt'
df=pd.read_csv(data_path,header=None)
print(df.info()) # 查看数据信息,确保没有错误
print(df.head())
print(df.tail())

第二步:用pd.date_range()建立时间序列数据

start=str(df.iloc[0,0])+'-'+str(df.iloc[0,1]) # 1940-1
if df.iloc[-1,1] %12 ==0: # 如果是12月结尾,需要转为第二年1月
    end=str(int(df.iloc[-1,0])+1)+'-01'
else:
    end=str(df.iloc[-1,0])+'-'+str(int(df.iloc[-1,1])+1)
print(end)

dates=pd.date_range(start,end,freq='M') # 构建以月为间隔的日期数据
print(dates[0])
print(dates[-1]) # 最后一个是2015-12 没有错误
print(len(dates))

注意上面有一个判断最后一个月是否是12月,因为date_range在freq为月的时候得到的结果不包含end所在的月份,故而此处我们要加上一个月份,使得最终日期的个数相同。

-------------------------------------输---------出--------------------------------

2016-01 1940-01-31 00:00:00 2015-12-31 00:00:00 912

--------------------------------------------完-------------------------------------

第三步:将时间序列数据设置为df的index

df.set_axis(dates)
print(df.info())
print(df.head())

从结果中可以看出,上面得到的dates日期数据已经变成了df这个数据集的index.

1.2 时间序列数据的绘图

pandas内部本来就集成了matplotlib这个函数的多种画图功能,故而我们可以直接画图,比如对所有的第二列数据画图,代码为:

# 画图
df.iloc[:,2].plot() # 画出第2列的时序数据

数据集第二列数据的时间序列图

上面图中数据量太大,导致密密麻麻看不清楚,故而我们需要只绘制一部分图来看清楚某一个时间段内的数据走势,可以用下列方法:

# 上面的图中数据太密集了,我们需要查看部分时间段的数据
start='2008-2'
end='2010-3'
df.iloc[:,2][start:end].plot() 
# 注意这种写法,先获取第二列数据为Series,然后对Series进行时间范围切片即可

时间段(2008-2至2010-3)的第二列数据走势图

也可以选择某几年的数据来绘图

start='2008' # 给定年份来获取数据
end='2010'
df.iloc[:,2][start:end].plot() 

时间段(2008-2010年)第二列数据走势图

上面每次只绘制一列数据,其实可以同时绘制多列数据,如下:

# 上面每次只绘制一列数据,下面同时绘制两列数据
start='2008' # 给定年份来获取数据
end='2010'
df.iloc[:,2:4][start:end].plot()  # 同时绘制第二列和第三列的数据

同时绘制第二列和第三列的数据

还可以绘制这两列数据之间的差,或和,或min,max等如下:

# 也可以绘制两列数据的差异
start='2008' # 给定年份来获取数据
end='2010'
temp_df=df.iloc[:,2][start:end]-df.iloc[:,3][start:end]
temp_df.plot()

绘制两列数据的差异

还可以绘制出某一列大于某值且另一列小于某值的一部分数据。

# 还可以筛选出第一个大于某个值,同时第二列小于某个值的数据来绘图
temp_df2=df[df.iloc[:,2]>60][df.iloc[:,3]<20].iloc[:,2:4]
temp_df2.plot()

对数据集进行大小筛选后绘图

1.3 获取统计数据

1.3.1 获取Max,Min,Mean等

# 获取数据集的统计数据
part_df=df.iloc[:,2:4] # 只取第二和第三列进行统计
print('Max: \n{}'.format(part_df.max()))
print('Min: \n{}'.format(part_df.min()))
print('Mean: \n{}'.format(part_df.mean()))
# 上面这个方法虽然可以获取Max,Min,Mean值,但是还不如下面这个函数好用

print(part_df.describe()) # 这个可以从整体上看出数据的分布情况

上面几个函数很简单,就不贴打印结果了。

1.3.2 计算移动平均值

移动平均值的意义主要是消除噪声,使得信号看起来更加的平滑,计算方法就是计算前面N个数据的平均值,然后在移动一位,始终计算最近N个数据的平均值。如果你会炒股,那么对移动平均线的意义和计算方法应该会了然于胸。

# 计算移动平均值MAn
N=20
MAn=part_df.rolling(N).mean()
MAn.plot()

移动平均线的绘制

1.3.3 计算移动平均值的相关系数

移动平均值的相关系数可以理解为:两列数据的相关性,如果相关性很强,那么这两列数据具有很强的关联,用股票数据来说明的话,移动平均值的相关性就是这两只股票的股价走势相关性,如果相关性很强,那么这两只股票会表现出同步的“同涨共跌”的走势,如果相关性很小,说明两个股票的价格走势没有太大关系。

# 计算移动平均值MAn的相关系数
N=20
MAn=part_df.rolling(N).mean()
corr=MAn.iloc[:,0].rolling(window=40).corr(MAn.iloc[:,1])
corr.plot()

两列数据的移动平均值的相关性图

########################小**********结###############################

1,这部分很多都是Pandas模块的基本方法,所以也没有太多要讲解的内容。

#################################################################


注:本部分代码已经全部上传到(我的github)上,欢迎下载。

参考资料:

1, Python机器学习经典实例,Prateek Joshi著,陶俊杰,陈小莉译