B
    ZQ              "   @   s  d Z ddlmZmZmZ ddlZddlmZ	 ddl
mZmZ ddlmZ ddlmZ d	d
 Zdd Zd:ddZG dd deZedkreddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3g Zeed4d5Zdd6lmZmZ eeed7eed8d9ZeeZdS );z+
Seasonal Decomposition by Moving Averages
    )lmaprange	iteritemsN)nanmean   )_maybe_get_pandas_wrapper_freq_maybe_get_pandas_wrapper)convolution_filter)freq_to_periodc                s   t  fddt D S )z
    Return means for each period in x. freq is an int that gives the
    number of periods per cycle. E.g., 12 for monthly. NaNs are ignored
    in the mean.
    c                s"   g | ]}t |d   ddqS )Nr   )axis)
pd_nanmean).0i)freqx 7lib/python3.7/site-packages/statsmodels/tsa/seasonal.py
<listcomp>   s    z!seasonal_mean.<locals>.<listcomp>)nparrayr   )r   r   r   )r   r   r   seasonal_mean   s    r   c       	      C   sp  t dd t| D }| jd d t dd t| ddd D  }t|| |}t||| }tjjtjt	||t
|| f | || ddd \}}t	d|tj|  tj|  j}| jdkr| }|| d|< tjjtjt	||t
|| f | || ddd \}}t	|d | jd tj|  tj|  j}| jdkr\| }|| |d d< | S )	z
    Replace nan values on trend's end-points with least-squares extrapolated
    values with regression considering npoints closest defined points.
    c             s   s&   | ]\}}t t |s|V  qd S )N)r   anyisnan)r   r   valsr   r   r   	<genexpr>   s    z%_extrapolate_trend.<locals>.<genexpr>r   r   c             s   s&   | ]\}}t t |s|V  qd S )N)r   r   r   )r   r   r   r   r   r   r      s    N)Zrcond)next	enumerateshapeminmaxr   ZlinalgZlstsqZc_ZarangeZonesTndimsqueeze)	trendZnpointsfrontZbackZ
front_lastZ
back_firstknZextrar   r   r   _extrapolate_trend   s&    ."
,r(   additiveTc             C   s  |dkrt | \}}nt| }d}t|  } t| }tt| sPtd|	drpt
| dkrptd|dkr|dk	rt|}|}ntd|dkr|d dkrtdgd	g|d	   dg | }ntd
| |}t|d	 }	t| ||	}
|dkr
|d	 }|dkr"t|
|d	 }
|	dr8| |
 }n| |
 }t||}|	drj|tj|dd }n|tj|dd8 }t|j|| d	 jd| }|	dr| | |
 }n|| }t|||
|| g}t|d |d	 |d |d dS )a  
    Seasonal decomposition using moving averages

    Parameters
    ----------
    x : array-like
        Time series. If 2d, individual series are in columns.
    model : str {"additive", "multiplicative"}
        Type of seasonal component. Abbreviations are accepted.
    filt : array-like
        The filter coefficients for filtering out the seasonal component.
        The concrete moving average method used in filtering is determined by two_sided.
    freq : int, optional
        Frequency of the series. Must be used if x is not a pandas object.
        Overrides default periodicity of x if x is a pandas
        object with a timeseries index.
    two_sided : bool
        The moving average method used in filtering.
        If True (default), a centered moving average is computed using the filt.
        If False, the filter coefficients are for past values only.
    extrapolate_trend : int or 'freq', optional
        If set to > 0, the trend resulting from the convolution is
        linear least-squares extrapolated on both ends (or the single one
        if two_sided is False) considering this many (+1) closest points.
        If set to 'freq', use `freq` closest points. Setting this parameter
        results in no NaN values in trend or resid components.

    Returns
    -------
    results : obj
        A object with seasonal, trend, and resid attributes.

    Notes
    -----
    This is a naive decomposition. More sophisticated methods should
    be preferred.

    The additive model is Y[t] = T[t] + S[t] + e[t]

    The multiplicative model is Y[t] = T[t] * S[t] * e[t]

    The seasonal component is first removed by applying a convolution
    filter to the data. The average of this smoothed series for each
    period is the returned seasonal component.

    See Also
    --------
    statsmodels.tsa.filters.bk_filter.bkfilter
    statsmodels.tsa.filters.cf_filter.xffilter
    statsmodels.tsa.filters.hp_filter.hpfilter
    statsmodels.tsa.filters.convolution_filter
    Nz,This function does not handle missing valuesmr   zJMultiplicative seasonality is not appropriate for zero and negative valueszhYou must specify a freq or x must be a pandas object with a timeseries index with a freq not set to None   g      ?r   g      ?r   )r      )seasonalr$   residobserved)r   r   r   Z
asanyarrayr#   lenallZisfinite
ValueError
startswithr   r
   r   repeatintr	   r(   r   ZmeanZtiler!   r   DecomposeResult)r   ZmodelZfiltr   Z	two_sidedZextrapolate_trendZ_pandas_wrapperZpfreqnobsZnsidesr$   Z	detrendedZperiod_averagesr-   r.   resultsr   r   r   seasonal_decompose5   sP    6
&



 r9   c               @   s   e Zd Zdd Zdd ZdS )r6   c             K   s2   x t |D ]\}}t| || q
W t| j| _d S )N)r   setattrr0   r/   r7   )selfkwargskeyvaluer   r   r   __init__   s    zDecomposeResult.__init__c             C   s`  ddl m} | }|jdddd\}}t| jdr| jj|d dd	 |d d
 | jj|d dd	 |d d | jj|d dd	 |d d | j	j|d dd	 |d d n|d | j |d d
 |d | j |d d |d | j |d d |d | j	 |d d |d 
d |d d| j |  |S )Nr   )_import_mpl   r   T)ZsharexplotF)ZaxZlegendZObservedZTrendr+   ZSeasonalr,   ZResidualZTime)Zstatsmodels.graphics.utilsr@   Zsubplotshasattrr/   rB   Z
set_ylabelr$   r-   r.   Z
set_xlabelZset_xlimr7   Ztight_layout)r;   r@   ZpltZfigZaxesr   r   r   rB      s0    zDecomposeResult.plotN)__name__
__module____qualname__r?   rB   r   r   r   r   r6      s   r6   __main__i                  iI  i  i)  i  i  i  i        iQ        f      i  r,   b   +   isii}   ii  i   rA   )r   )	DataFrameDatetimeIndexz1/1/1951Q)startZperiodsr   )r)   NNTr   ) __doc__Zstatsmodels.compat.pythonr   r   r   Znumpyr   Zpandas.core.nanopsr   r   Zfilters._utilsr   r   Zfilters.filtertoolsr	   Zstatsmodels.tsa.tsatoolsr
   r   r(   r9   objectr6   rD   r   r   r8   ZpandasrX   rY   r0   dataZresr   r   r   r   <module>   s*   	 
t#

