zoukankan      html  css  js  c++  java
  • Python数据分析_Pandas_窗函数

    窗函数(window function)经常用在频域信号分析中。我其实不咋个懂,大概是从无限长的信号中截一段出来,然后把这一段做延拓变成一个虚拟的无限长的信号。用来截取的函数就叫窗函数,窗函数又分很多种,什么矩形窗、三角窗、高斯窗。

    scipy.signal中有各种我不懂的实现窗函数的方法。浏览了一下,头疼的紧。

    那在pandas中也有实现窗函数的方法:rolling()。我呢就不折腾什么信号处理的东西,用金融数据做个小示例好了。

    金融时间序列也是一种时间序列数据,前后次序是固定,多为二维数据。例如要看一只股票的平均移动线,就会用到rolling()

    先介绍一下这个翻滚函数

    DataFrame.rolling(window, 
                      min_periods=None, 
                      freq=None, 
                      center=False, 
                      win_type=None, 
                      on=None, 
                      axis=0)
    
    • window: 移动窗口的大小。值可以是int(整数值)或offset(偏移)。如果是整数值的话,每个窗口是固定的大小,即包含相同数量的观测值。值为offset(偏移时长,eg:'2s')则指定了每个窗口包含的时间段,每个窗口包含的观测值的数量是不一定的。offset必须在index是时间类型数据时才可以使用。

    • min_periods: 每个窗口最少包含的观测值数量,小于这个值的窗口结果为NA。值可以是int,默认None。offset情况下,默认为1。

    • freq: 弃用。不用管它。

    • center: 把窗口的标签设置为居中。布尔型,默认False,居右。

    • win_type: 窗口的类型。上面介绍的,截取窗的各种函数。字符串类型,默认为None。可用的窗口类型有:

      • boxcar
      • triang
      • blackman
      • hamming
      • bartlett
      • parzen
      • bohman
      • blackmanharris
      • nuttall
      • barthann
      • kaiser (needs beta)
      • gaussian (needs std)
      • general_gaussian (needs power, width)
      • slepian (needs width)
    • on: 可选参数。对于dataframe而言,指定要计算滚动窗口的列。值为列名。

    • axis: int、字符串,默认为0,即对列进行计算。

    使用方法,例:

    In []: df = pd.DataFrame({'B': [0, 1, 2, np.nan, 4]})
    
    In []: df.rolling(2).sum()
    Out[]:
         B
    0  NaN
    1  1.0
    2  3.0
    3  NaN
    4  NaN
    

    按tab键可以查看rolling对象可用的方法,如下:

    In []: r = df.rolling(2)
    In []: r
    Out[]: Rolling [window=10,center=False,axis=0]
    
    In []: r.
       r.agg             r.cov             r.max             r.ndim
       r.aggregate       r.exclusions      r.mean            r.quantile
       r.apply           r.is_datetimelike r.median          r.skew
       r.corr            r.is_freq_type    r.min             r.std
       r.count           r.kurt            r.name            r.sum
    

    注:rolling_mean()这种写法已经淘汰了,现在都是df.rolling().mean()df.rolling().std()这样来写。

    例:计算苹果收盘价的平均移动线

    获取数据

    从雅虎获取苹果公司2016年1月1日至今的股票数据。

    import pandas_datareader.data as web
    
    apple = web.DataReader(name='AAPL', 
                           data_source='yahoo', 
                           start='2016-1-1')
    print(apple.head())
    

    数据大概是这个样子的:

                      Open        High         Low       Close    Volume  
    Date
    2016-01-04  102.610001  105.370003  102.000000  105.349998  67649400
    2016-01-05  105.750000  105.849998  102.410004  102.709999  55791000
    2016-01-06  100.559998  102.370003   99.870003  100.699997  68457400
    2016-01-07   98.680000  100.129997   96.430000   96.449997  81094400
    2016-01-08   98.550003   99.110001   96.760002   96.959999  70798000
    
                 Adj Close
    Date
    2016-01-04  103.057063
    2016-01-05  100.474523
    2016-01-06   98.508268
    2016-01-07   94.350769
    2016-01-08   94.849671
    

    收盘价的折线图

    为了方便观察滚完了之后的效果,我们把数据都画图呈现出来。

    apple['Close'].plot(figsize=(9, 5), grid=True)
    plt.show()
    
     
    收盘价

    平均移动线MA

    apple['roll_mean'] = apple['Close'].rolling(window=5).mean()
    apple[['Close', 'roll_mean']].plot(subplots=True, figsize=(9, 5), grid=True)
    plt.show()
    
     
    收盘价和5日平均移动线

    这里窗口大小为5,所以前面四个数据是没有值的。把它们合在一起看看(把subplots改为False)。

     
    收盘价和5日平均移动线合在一起

    拉近一点:

     
     

    直观上看更平滑了。毕竟取五天做平均了,第一天涨第二天跌的这种一平均波动就小了。如果窗口变大会更平滑。

    windowsize = [5,10,20]
    for i in windowsize:
        apple['roll_mean_'+str(i)] = apple['Close'].rolling(i).mean()
    apple[['roll_mean_5','roll_mean_10','roll_mean_20']].plot(figsize=(9, 5), grid=True)
    plt.show()
    
     
     

    补充

    除了算平均值,还可以计算方差、相关、最大最小值等等,大部分的统计量都可以计算,就看你需要了。

    另外如果已有的函数不能满足需要,我们还可以用lambdaapply()写自己的方法。

    例如(直接复制官网的咯):

    mad = lambda x: np.fabs(x - x.mean()).mean()
    apple['Close'].rolling(window=5).apply(mad).plot(figsize=(9, 5), grid=True)
    plt.show()
    

    这里计算的是平均绝对偏差。

     
     

    我的图长得漂亮是因为安装了seaborn库,画图之前悄悄加载了一下。

    另外,pandas中也有好些金融函数,比如计算指数加权移动平均,就现成的pandas.ewma()。待挖掘的东西好多呢。



    作者:ChZ_CC
    链接:https://www.jianshu.com/p/f6e489de57f7
    來源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 相关阅读:
    查找 Linux 父进程的方法
    Flask 使用日志
    Jenkins Pipeline 编译后端 Java 代码
    K8S 指定 nfs 挂载
    K8S ingress nginx 设置访问白名单
    Jenkins Pipeline 编译前端 NodeJS 代码
    在 K8S 中测试环境中搭建 mongodb
    K8S argocd 安装配置
    搭建私有 helm 仓库 chartmuseum
    Helm templates 中的语法
  • 原文地址:https://www.cnblogs.com/jingsupo/p/python-pandas-rolling.html
Copyright © 2011-2022 走看看