时间序列分析¶
这个例子的作者是Nikolay Koldunov,节取自他的系列文章Python for Geosciences notes.原文请参见 https://github.com/koldunovn/python_for_geosciences/blob/master/06%20-%20Time%20series%20analysis%20(Pandas).ipynb
本文介绍了利用pandas包进行时间序列分析的例子,作者指出,事实上一维数据都可以利用pandas高效地解决
注:Docklet上pandas的版本号和原作者不同,部分实例输出结果有细节上的差别,这里我们以Docklet上的运行结果为准,但不影响数据处理的结果
引用需要的模块¶
首先我们引用必要的模块
import pandas as pd
import numpy as np
pd.set_option('max_rows',15) # 这里限制了行数的最大值
打开笔记本内嵌的显示图形功能:
%matplotlib inline
pandas发展快速,即便我们只使用基本的功能,一些实现上的细节在新版本中仍可能有变化
pd.__version__
加载数据¶
现在我们做些准备工作,获取数据。可以直接使用wget命令:
!wget http://www.cpc.ncep.noaa.gov/products/precip/CWlink/daily_ao_index/monthly.ao.index.b50.current.ascii
实际上pandas拥有强大的I/O能力,但这个例子中我们并不涉及。这里简单地用numpy loadtxt打开文件:
ao = np.loadtxt('monthly.ao.index.b50.current.ascii')
文件中的每一行包含三项:年、月、值:
ao[0:2]
可以查看数组的形式(shape):
ao.shape
时间序列¶
我们希望自然而简单地将这些数据转换成时间序列。作为第一步,我们选定我们的时间序列的时间范围。从文件可以很清晰地看出时间起点是2013年1月(此时作者开始写作本系列文章),你可以根据自己的文件调整截止时间。数据的频率(两次数据的时间间隔)是月。
dates = pd.date_range('1950-01', '2014-01', freq='M')
如你所见,Pandas语法简单,这正是作者喜欢它的原因之一。另外请注意,截止时间参数设成了2014-01而不是2013-12,因为区间右侧是开的
dates
dates.shape
现在我们开始创建我们的第一个事件序列。变量dates所标明的日期将作为索引,AO值则作为我们的值。下面我们就用截止到2013年底的数据进行分析。
AO = pd.Series(ao[:768,2], index=dates)
AO
我们可以绘制出完整的时间序列:
AO.plot()
也可以绘制出其中的一部分:
AO['1980':'1990'].plot()
甚至更小的区间:
AO['1980-05':'1981-03'].plot()
参照时间以一种很自然的方式完成了。你也可以找某一个时间点,可以通过序号:
AO[120]
或者通过索引(我们选定了date所标明的日期):
AO['1960-01']
也可以尝试查看一年的数据:
AO['1960']
Data Frame¶
下面我们做一些更有趣的尝试。首先下载更多数据:
!wget http://www.cpc.ncep.noaa.gov/products/precip/CWlink/pna/norm.nao.monthly.b5001.current.ascii
创建nao序列,就像之前创建AO序列一样,时间区间也一样:
nao = np.loadtxt('norm.nao.monthly.b5001.current.ascii')
dates_nao = pd.date_range('1950-01', '2014-01', freq='M')
NAO = pd.Series(nao[:768,2], index=dates_nao)
NAO.index
现在我们创建Data Frame,它将包含AO和NAO数据。可以直接绘制出数据:
aonao = pd.DataFrame({'AO' : AO, 'NAO' : NAO})
aonao.plot()
我们可以查看最初的几行:
aonao.head()
我们可以通过列名查看每一列:
aonao['NAO']
或者通过DATA FRAME变量的方法查看:
aonao.NAO
可以很容易地添加列:
aonao['Diff'] = aonao['AO'] - aonao['NAO']
aonao.head()
也可以很容易地删除列:
del aonao['Diff']
aonao.tail()
依然可以查看子区间:
aonao['1981-01':'1981-03']
甚至以一组组合条件约束:
import datetime
aonao.ix[(aonao.AO > 0) & (aonao.NAO < 0)
& (aonao.index > datetime.datetime(1980,1,1))
& (aonao.index < datetime.datetime(1989,1,1)),
'NAO'].plot(kind='barh')
重采样¶
这里列出作者的最后一个综合性例子。Pandas提供了简单的重采样方法,两个主要参数分别是采样频率(“A”是一年,类似地,三年则是“3A”),采样方式,后者默认值是mean.
可以将多个重采样一并展示出来:
AO_mm = AO.resample("A", how=['mean', np.min, np.max])
AO_mm['1900':'2020'].plot()