文章数据
收藏(次)
【python数据分析】第十一章 时间序列-4
重采样及频率转换
--------------------------------------------------------------------------------
重采样(resampling)指的是将时间序列从一个频率转换到另一个频率的处理过程。
将高频率数据聚合到低频率称为降采样(downsampling),而将低频率数据转换到高频率则
称为升采样(upsampling)。并不是所有的重采样都能被划分到这两个大类中。
例如,将W-WED(每周三)转换为W-FRI既不是降采样也不是升采样。
pandas对象都带有一个resample方法,它是各种频率转换工作的主力函数。resample有一个
类似于groupby的API,调用resample可以分组数据,然后会调用一个聚合函数:
--------------------------------------------------------------------------------
rng = pd.date_range('2000-01-01', periods=100, freq='D')
ts = pd.Series(np.random.randn(len(rng)), index=rng)
ts 每天一个数据
ts.resample('M') # 重新采样为每月一个数据,就像是分组,重采样后得到的一组一组的数据
ts.resample('M').sum() # 对组数据就是用聚合函数呗
--------------------------------------------------------------------------------
参数:kind : {'timestamp', 'period'}, optional, default None
ts.resample('M', kind='period').sum() # 重新采用可以改变点时间为区间时间
--------------------------------------------------------------------------------
方法定义:
ts.resample(
rule, 就是频率了,DateOffset, Timedelta or str
axis=0,
closed: Union[str, NoneType] = None, 降采样时数据区间那个闭合 [ ) 还是 ( ]
label: Union[str, NoneType] = None,
convention: str = 'start',
kind: Union[str, NoneType] = None,
loffset=None, 时间范围容易让人不理解,一个时间到底时属于前面还是,后面,使用这个偏移1秒,清楚了
base: int = 0,
on=None,
level=None,
)
Docstring:
Resample time-series data.
--------------------------------------------------------------------------------
OHLC重采样
金融领域中有一种无所不在的时间序列聚合方式,即计算各面元的四个值:第一个
值(open,开盘)、最后一个值(close,收盘)、最大值(high,最高)以及最
小值(low,最低)。传入how='ohlc'即可得到一个含有这四种聚合值的
--------------------------------------------------------------------------------
ts.resample('5min').ohlc()
输出:
open high low close
2000-01-01 00:00:00 0 4 0 4
2000-01-01 00:05:00 5 9 5 9
2000-01-01 00:10:00 10 11 10 11
--------------------------------------------------------------------------------
升采样和插值:
降采样是每天一天数据变成一月一条,数据需要聚合计算,把30条数据变成1条
升采样是一条月数据,变成30条日数据,这个不是上面的逆运算,因为聚合后数据细节丢失。需要按一定规则插值
--------------------------------------------------------------------------------
frame = pd.DataFrame(np.random.randn(2, 4),
index=pd.date_range('1/1/2000', periods=2,freq='W-WED'),
columns=['Colorado', 'Texas', 'New York', 'Ohio'])
df_day = frame.resample('D') # 每周一条数据升采样为每天一条,得到 DatetimeIndexResampler 对象
df_day.asfreq() # Return the values at the new freq, essentially a reindex.,没有插值,是空值
df_day.ffill() # 使用前值作为插值
df_day.bfill() # 使用后值作为插值
df_day.ffill(limit=2) # 使用前值插值,只插值2个
df_day = frame.resample('w-thu').asfreq() # 频率还是一样的,只是改一下时间
--------------------------------------------------------------------------------
frame = pd.DataFrame(np.random.randn(24, 4),
index=pd.period_range('1-2000', '12-2001', freq='M'),
columns=['Colorado', 'Texas', 'New York', 'Ohio'])
annual_frame = frame.resample('A-DEC').mean() # 2年的月数据,变成年数据,细节丢失
# 月数据变成季度数据,只能采用插值的方式
annual_frame.resample('Q-DEC', convention='end').ffill()
annual_frame.resample('Q-DEC', convention='start').ffill()
================================================================================
移动窗口函数
--------------------------------------------------------------------------------
frame = pd.DataFrame({'d1': np.arange(20)},
index=pd.date_range('2003-1-1', freq='D', periods=20))
frame 输出:
d1
2003-01-01 0
2003-01-02 1
2003-01-03 2
2003-01-04 3
2003-01-05 4
2003-01-06 5
2003-01-07 6
......
frame['d1'].rolling(3).mean()
移动计算:
rolling(3) 就是移动的每三天计算一次聚合,比如这里是每三天聚合一次,计算平均值。
(1,2,3) (2,3,4) (3,4,5) (4,5,6) ..... 这样每三天计算一次,得到3日移动平均线
计算的结果还保存在原索引的位置,由于第1,2天的时候数据量不足3,这两天不计算,为NA,
从第三天的时候就能就算了
frame['d1'].rolling(3).mean()
输出:
2003-01-01 NaN
2003-01-02 NaN
2003-01-03 1.0
2003-01-04 2.0
2003-01-05 3.0
......
如果想画一个图,那就画一个:
frame['d1'].rolling(3).mean().plot()
--------------------------------------------------------------------------------
一个问题是,如果 rolling(N) N很大,那么前面一段一直没有数据。使用 min_periods 指定
有几个数据的时候就开始计算,比如这里指定为1, 即有1个数据的时候就计算了,
两个数据的时候也是两个数据的平均,.....
frame['d1'].rolling(3, min_periods=1).mean()
--------------------------------------------------------------------------------
rolling 是固定窗口期内数据的计算,那么如果计算数据到目前位置是什么状态呢?
比如,学生挨个量身高,量完一个就重新计算到目前为止平均身高是多少。
frame['d1'].expanding().sum() # 需要用到 expanding, 每次计算开始到当前位置的数据均值
还能指定运算时最少多少个数据
frame['d1'].expanding(min_periods=3).sum()
--------------------------------------------------------------------------------
加权移动聚合,比如有100年的数据,通过这一百年的数据预测数据的未来变化,
这时去年的数据肯定比100年前的数据更有参考价值如果计算一个平均值,是100个数据加起来/100
得到的数据可能不能代表数据的趋势,如果给数据按照年份进行加权的话可能好一点。
年份: 100 99 ... 50 .... 2 1 第N年前前的标记
权重: 0.01 0.011 0.1 0.3 0.5 权重加起来等于1
数据: 123 231 212 456 467 平均值 = 连加([原数据i * 权重i]) / 100
pandas 中有 ewm 就是这个功能, 权重有几种方式,比如按照时间进行权重...
frame['d1'].ewm(span=30).mean()
功能和 rolling 还是相同就是计算的时候考虑权重即可。
--------------------------------------------------------------------------------
二元移动窗口函数
--------------------------------------------------------------------------------
用户定义的移动窗口函数:roling 来移动数据,把移动额数据给到 apply 的回调方法
回调的方法要求就是接收一组数据,返回一个数据即可,比如这里返回2倍均值
frame['d1'].rolling(4).apply(lambda x : x.mean() * 2)
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
分享
收藏
点赞人
举报
文章标签
评论列表