U
    md$,                     @   s   d Z ddl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lmZ ddlmZ d	d
dddgZdd Zdd Zddd
ZG dd dZdS )z+
Seasonal Decomposition by Moving Averages
    N)nanmean)PandasWrapper
array_like)STL)convolution_filter)MSTL)freq_to_periodr   seasonal_decomposeseasonal_meanDecomposeResultr   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npanyisnan.0ivals r   Q/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/statsmodels/tsa/seasonal.py	<genexpr>   s     z%_extrapolate_trend.<locals>.<genexpr>r      c                 s   s&   | ]\}}t t |s|V  qd S 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npointsZfrontbackZ
front_lastZ
back_firstknextrar   r   r   _extrapolate_trend   sH    	
"

,r'   c                    s   t  fddt D S )z
    Return means for each period in x. period 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   Zaxis)
pd_nanmean)r   r   periodxr   r   
<listcomp>H   s     z!seasonal_mean.<locals>.<listcomp>)r   arrayrange)r,   r+   r   r*   r   r
   B   s    additiveTc                 C   sT  |}t | }|dkr(tt| dddd}t| ddd} t| }tt| sVtd|drvt	| d	krvtd
|dkr|dk	rt
|}|}ntd| jd	 d| k rtdd|  d| jd	  d|dkr|d d	krtdgdg|d   dg | }ntd| |}t|d }	t| ||	}
|dkrF|d }|d	kr^t|
|d }
|drt| |
 }n| |
 }t||}|dr|tj|d	d }n|tj|d	d8 }t|j|| d jd| }|dr| | |
 }n|| }g }t||
|| fdD ]"\}}||j| |d q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. x must contain 2
        complete cycles.
    model : {"additive", "multiplicative"}, optional
        Type of seasonal component. Abbreviations are accepted.
    filt : array_like, optional
        The filter coefficients for filtering out the seasonal component.
        The concrete moving average method used in filtering is determined by
        two_sided.
    period : int, optional
        Period of the series. Must be used if x is not a pandas object or if
        the index of x does not have  a frequency. Overrides default
        periodicity of x if x is a pandas object with a timeseries index.
    two_sided : bool, optional
        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
    -------
    DecomposeResult
        A object with seasonal, trend, and resid attributes.

    See Also
    --------
    statsmodels.tsa.filters.bk_filter.bkfilter
        Baxter-King filter.
    statsmodels.tsa.filters.cf_filter.cffilter
        Christiano-Fitzgerald asymmetric, random walk filter.
    statsmodels.tsa.filters.hp_filter.hpfilter
        Hodrick-Prescott filter.
    statsmodels.tsa.filters.convolution_filter
        Linear filtering via convolution.
    statsmodels.tsa.seasonal.STL
        Season-Trend decomposition using LOESS.

    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 results are obtained by first estimating the trend by applying
    a convolution filter to the data. The trend is then removed from the
    series and the average of this de-trended series for each period is
    the returned seasonal component.
    NindexZinferred_freqr,      )Zmaxdimz,This function does not handle missing valuesmr   zJMultiplicative seasonality is not appropriate for zero and negative valueszxYou must specify a period or x must be a pandas object with a PeriodIndex or a DatetimeIndex with a freq not set to Nonez'x must have 2 complete cycles requires z observations. x only has z observation(s)g      ?r   g      ?freqr(   )seasonalr"   residN)columns   )r5   r"   r6   observed)r   getattrr   lenr   allisfinite
ValueError
startswithr   r   r   r.   repeatintr   r'   r
   ZmeanZtiler   zipappendwrapr!   r   )r,   modelZfiltr+   Z	two_sidedZextrapolate_trendZpfreqpwnobsZnsidesr"   Z	detrendedZperiod_averagesr5   r6   resultssnamer   r   r   r	   K   sr    E

&



 
 c                   @   sl   e Zd ZdZdddZedd Zedd Zed	d
 Zedd Z	edd Z
edd ZdddZdS )r   a  
    Results class for seasonal decompositions

    Parameters
    ----------
    observed : array_like
        The data series that has been decomposed.
    seasonal : array_like
        The seasonal component of the data series.
    trend : array_like
        The trend component of the data series.
    resid : array_like
        The residual component of the data series.
    weights : array_like, optional
        The weights used to reduce outlier influence.
    Nc                 C   sR   || _ || _|d kr<t|}t|tjr<tj||jdd}|| _|| _	|| _
d S )Nweights)r1   rJ   )	_seasonal_trendr   Z	ones_like
isinstancepdSeriesr1   _weights_resid	_observed)selfr9   r5   r"   r6   rK   r   r   r   __init__   s    
  zDecomposeResult.__init__c                 C   s   | j S )zObserved data)rS   rT   r   r   r   r9      s    zDecomposeResult.observedc                 C   s   | j S )z The estimated seasonal component)rL   rV   r   r   r   r5     s    zDecomposeResult.seasonalc                 C   s   | j S )zThe estimated trend component)rM   rV   r   r   r   r"     s    zDecomposeResult.trendc                 C   s   | j S )zThe estimated residuals)rR   rV   r   r   r   r6     s    zDecomposeResult.residc                 C   s   | j S )z)The weights used in the robust estimation)rQ   rV   r   r   r   rK     s    zDecomposeResult.weightsc                 C   s   | j jS )zNumber of observations)rS   r   rV   r   r   r   rG     s    zDecomposeResult.nobsTFc                 C   sH  ddl m} ddlm} | }|  |r4| jdfgng }	|	|rJ| jdfgng 7 }	| jjdkrv|	|rn| jdfgng 7 }	n| jjdkrt| jt	j
r| jjD ] }
|	|r| j|
 dfgng 7 }	qn:t| jjd D ](}|	|r| jdd|f dfgng 7 }	q|	|r
| jd	fgng 7 }	|	|r$| jd
fgng 7 }	t| jt	j
t	jfrj| jjd }| jjd | jj|d  f}nd| jjd d f}|jt|	ddd\}}tt||	D ]\}\}\}	}|d	kr||	 n"|j|	ddd |j|dddd t|	d|}|dkr
| }|dkr |r |jn|j}|| || q|  |S )a@  
        Plot estimated components

        Parameters
        ----------
        observed : bool
            Include the observed series in the plot
        seasonal : bool
            Include the seasonal component in the plot
        trend : bool
            Include the trend component in the plot
        resid : bool
            Include the residual in the plot
        weights : bool
            Include the weights in the plot (if any)

        Returns
        -------
        matplotlib.figure.Figure
            The figure instance that containing the plot.
        r   )register_matplotlib_converters)_import_mplZObservedr"   r   r5   NZresidualrK   T)Zsharexonone)markerZ	linestyle)r   r   z#000000)colorZzorderrJ   )Zpandas.plottingrW   Zstatsmodels.graphics.utilsrX   rS   r"   r5   r    rN   rO   Z	DataFramer7   r/   r   r6   rK   rP   r1   Zsubplotsr;   r   rB   plotr:   
capitalize	set_titleZ
set_ylabelZset_xlimZtight_layout)rT   r9   r5   r"   r6   rK   rW   rX   ZpltZseriescolr   rG   ZxlimZfigZaxsZaxZdef_namerJ   titler   r   r   r^     sL    

zDecomposeResult.plot)N)TTTTF)__name__
__module____qualname____doc__rU   propertyr9   r5   r"   r6   rK   rG   r^   r   r   r   r   r      s(   






     )r0   NNTr   )rf   numpyr   ZpandasrO   Zpandas.core.nanopsr   r)   Zstatsmodels.tools.validationr   r   Zstatsmodels.tsa.stl._stlr   Z#statsmodels.tsa.filters.filtertoolsr   Zstatsmodels.tsa.stl.mstlr   Zstatsmodels.tsa.tsatoolsr   __all__r'   r
   r	   r   r   r   r   r   <module>   s0   	+     
 