目录
时间序列绘图
移动窗口函数
指数加权函数
二元移动窗口函数
用户自定义的移动窗口函数
性能和内存使用方面的注意事项
时间序列绘图
>>> import pandas as pd
Backend TkAgg is interactive backend. Turning interactive mode on.
>>> import numpy as np
>>> from pandas import DataFrame,Series
>>> close_px_all = pd.read_csv('D:\python\DataAnalysis\data\stock_px.csv',parse_dates=True,index_col=0)
>>> close_px = close_px_all[['AAPL','MSFT','XOM']]
>>> close_px = close_px.resample('B').ffill()
>>> close_px
AAPL MSFT XOM
1990-02-01 7.86 0.51 6.12
1990-02-02 8.00 0.51 6.24
1990-02-05 8.18 0.51 6.25
1990-02-06 8.12 0.51 6.23
1990-02-07 7.77 0.51 6.33
... ... ...
2011-10-12 402.19 26.96 77.16
2011-10-13 408.43 27.18 76.37
2011-10-14 422.00 27.27 78.11
[5662 rows x 3 columns]
close_px['AAPL'].plot()
切片2009年数据,所欲数据都被绘制在subplot上,并且月份和年度都被格式化到X轴上
close_px.ix['2009'].plot()
苹果公司的股价波动,2011年1月到3月
close_px['AAPL'].ix['01-2011':'03-2011'].plot()
季度型频率数据会用季度标记进行格式化
>>> appl_q = close_px['AAPL'].resample('Q-DEC').ffill()
>>> appl_q.ix['2009':].plot()
移动窗口函数
在移动窗口上计算的各种统计函数也是一类常见于时间序列的数组变换。我们将他们称谓移动窗口函数-moving window function
其中还包括那些窗口不定长的函数,跟其他函数一样,移动窗口会自动排除缺失值。
下面为苹果公司250日均价
>>> close_px['AAPL'].rolling(250).mean().plot()
苹果公司250日每日回报标准差
>>> appl_std250 = close_px['AAPL'].rolling(250).std(min_periods=10)
要计算扩展窗口平均-expending window mean,你可以将扩展窗口看作一个特殊的窗口,其长度于时间序列一样,但是需一期或多期即可计算一个值
个股价的60日均线
close_px.rolling(60).mean().plot(logy=True)
*这里的函数是旧版本的,新版本为单独rolling函数和气压函数组合,如rolling_count--->>>rolling().count()
指数加权函数
另一种使用固定大小窗口及相等权数观测值的办法是,定义一个衰减因子常量-decay factor,以便使近期的观测值拥有更大的权数,用数学术语来讲如果mat是时间t的移动平均结果,x是时间序列,结果中的各个值可用mat = a*mat-1 + (a-1)*x-t ----斜体字为下角标 进行计算,其中a为衰减因子。衰减因子的定义方式有很多,比较流行的是使用时间间隔--span,他可以使结果兼容于窗口大小等于时间间隔的简单移动窗口函数--simple moving windows
由于指数加权统计会赋予近期的观测值更大的权数,因此相对于等权统计,他能适应更快的变化。
下面的例子对比了苹果公司股价的60日移动平均和span=60的指数加权移动平均。
*有一个函数不好使了,方法会一种即可
>>> import matplotlib.pyplot as plt
>>> fig,axes = plt.subplots(nrows=2,ncols=1,sharex=True,sharey=True,figsize=(12,7))
>>> aapl_px = close_px.AAPL['2005':'2009']
>>> ewma60 = aapl_px.ewm(span=60)
>>> aapl_px.plot(style='g-',ax=axes[0])
<matplotlib.axes._subplots.AxesSubplot object at 0x00000000146912B0>
>>> ma60.plot(style='r--',ax=axes[1])
<matplotlib.axes._subplots.AxesSubplot object at 0x000000001468EC18>
>>> aapl_px.plot(style='g-',ax=axes[1])
<matplotlib.axes._subplots.AxesSubplot object at 0x000000001468EC18>
二元移动窗口函数
有些统计运算需要在两个时间序列上执行,我们可以计算百分比变化
>>> spx_px = close_px_all['SPX']
>>> spx_rets = spx_px/spx_px.shift(1)-1
>>> returns = close_px.pct_change()
>>> corr = returns['AAPL'].rolling(125,min_periods=100).corr(spx_rets)
corr.ix['2003':'2011'].plot()
<matplotlib.axes._subplots.AxesSubplot object at 0x0000000018CCC710>
AAPL6个月的回报与标准普尔500指数的相关系数
3只股票6个月的回报与标准普尔500指数的相关系数
用户自定义的移动窗口函数
from scipy.stats import percentileofscore
score_at_2percent = lambda x: percentileofscore(x,0.02)
result = returns['AAPL'].rolling(250).apply(score_at_2percent)
result.ix['2004':'2011'].plot()
<matplotlib.axes._subplots.AxesSubplot object at 0x000000001120CC88>
性能和内存使用方面的注意事项
Timestamp和Period都是以64位整数表示的,也就是说,对于每个数据点,其时间戳需要占用8个字节的内存,因此含有一百万个float64数据点的时间序列需要占用大约16mb的内存空间。由于pandas会尽量在多个时间序列之间共享索引,所以创建现有时间序列的视图不会占用更多内存。
此外,低频率索引会被存放在一个中心缓存中,所以任何固定频率的索引都是该日期缓存的视图,所以当你有一个很大的低频率时间序列时,索引所占用的内存空间将不会很大。
下面例子对一亿个数据点聚合为OHLC,运算时间跟聚合结果的相对大小有一定关系,越高频率的聚合所耗费的时间越多:
>>> rng = pd.date_range('1/1/2000',periods=100000000,freq='10ms')
>>> ts = Series(np.random.randn(len(rng)),index=rng)
>>> ts[-10:]
2000-01-12 13:46:39.900 0.475186
2000-01-12 13:46:39.910 -1.638490
2000-01-12 13:46:39.920 -1.366791
2000-01-12 13:46:39.930 -0.918726
2000-01-12 13:46:39.940 0.282643
2000-01-12 13:46:39.950 -1.781787
2000-01-12 13:46:39.960 1.540807
2000-01-12 13:46:39.970 1.151918
2000-01-12 13:46:39.980 -0.839410
2000-01-12 13:46:39.990 -0.042157
Freq: 10L, dtype: float64
>>> ts.resample('15min',how='ohlc')