U
    Cvfe                     @  s  d dl mZ d dlZd dlZd dlZd dlZd dlmZmZm	Z	m
Z
mZmZmZmZ d dlZd dlmZmZmZ d dlmZ d dlmZmZ d dlmZ d dlmZmZmZ d d	l m!Z! zd dl"Z"W n e#k
r   dZ"Y nX erd d
l$m%Z% d dl&m'Z' eZ(edZ)dZ*G dd de
e Z+G dd de+d Z,G dd de+d Z-G dd dee
e Z.G dd de.d Z/G dd de.d Z0dS )    )annotationsN)TYPE_CHECKINGAnyCallableGenericHashableIteratorMappingTypeVar)dtypesduck_array_opsutils)CoarsenArithmetic)OPTIONS_get_keep_attrs)is_duck_dask_array)CoarsenBoundaryOptionsSideOptionsT_Xarray)either_dict_or_kwargs	DataArrayDataset_Ta  Reduce this object's data windows by applying `{name}` along its dimension.

Parameters
----------
keep_attrs : bool, default: None
    If True, the attributes (``attrs``) will be copied from the original
    object to the new one. If False, the new object will be returned
    without attributes. If None uses the global default.
**kwargs : dict
    Additional keyword arguments passed on to `{name}`.

Returns
-------
reduced : same type as caller
    New object with `{name}` applied along its rolling dimension.
c                   @  sH  e Zd ZdZdZdZd=dddd	d
dddZddddZddddZe	ddddZ
d>dddddddZdd Zejdd e_ed!ejZed"ejZed#ejZed$ejZed%d&Zed'd(ZeddeZed)dZed*dZed+dZd,dd-d.d/Zd?d,dd-d0d1Zejd2d e_d@d4d5d6d6d7d8d9d:Zd;d< ZdS )ARollingzA object that implements the moving window pattern.

    See Also
    --------
    xarray.Dataset.groupby
    xarray.DataArray.groupby
    xarray.Dataset.rolling
    xarray.DataArray.rolling
    )objwindowmin_periodscenterdim)r   r   r   r    NFr   Mapping[Any, int]
int | Nonebool | Mapping[Any, bool]Noner   windowsr   r   returnc                 C  s   g | _ g | _| D ]0\}}| j | |dkr8td| j| q| j|dd| _|| _|dk	rt|dkrttd|dkrt	| jn|| _
dS )ac  
        Moving window object.

        Parameters
        ----------
        obj : Dataset or DataArray
            Object to window.
        windows : mapping of hashable to int
            A mapping from the name of the dimension to create the rolling
            window along (e.g. `time`) to the size of the moving window.
        min_periods : int or None, default: None
            Minimum number of observations in window required to have a value
            (otherwise result is NA). The default, None, is equivalent to
            setting min_periods equal to the size of the window.
        center : bool or dict-like Hashable to bool, default: False
            Set the labels at the center of the window. If dict-like, set this
            property per rolling dimension.

        Returns
        -------
        rolling : type of input argument
        r   zwindow must be > 0FdefaultNz-min_periods must be greater than zero or None)r    r   itemsappend
ValueError_mapping_to_listr   r   mathprodr   )selfr   r&   r   r   dw r3   7/tmp/pip-unpacked-wheel-h316xyqg/xarray/core/rolling.py__init__I   s    zRolling.__init__strr'   c                 C  s4   dd t | j| j| jD }dj| jjd|dS )z-provide a nice str repr of our rolling objectc                 S  s*   g | ]"\}}}d j |||rdnddqS )z{k}->{v}{c}z(center) )kvc)format).0r9   r2   r;   r3   r3   r4   
<listcomp>|   s   z$Rolling.__repr__.<locals>.<listcomp>{klass} [{attrs}],klassattrs)zipr    r   r   r<   	__class____name__joinr0   rC   r3   r3   r4   __repr__y   s     zRolling.__repr__intc                   s   t  fdd jD S )Nc                 3  s   | ]} j j| V  qd S N)r   sizesr=   r1   r0   r3   r4   	<genexpr>   s     z"Rolling.__len__.<locals>.<genexpr>)r.   r/   r    rN   r3   rN   r4   __len__   s    zRolling.__len__c                 C  s
   t | jS rK   )lenr    rN   r3   r3   r4   ndim   s    zRolling.ndimr   zCallable | NonezCallable[..., T_Xarray])namefillnarolling_agg_funcr'   c                   sP   r
d n
t t|  t td|  dd fdd	}| |_tj| d|_|S )zConstructs reduction methods built on a numpy reduction function (e.g. sum),
        a bottleneck reduction function (e.g. move_sum), or a Rolling reduction (_mean).NZmove_c                   s&   |  |}| j f|d|S )N)
keep_attrsrT   )r   _numpy_or_bottleneck_reduce)r0   rV   kwargsarray_agg_funcbottleneck_move_funcrT   rU   r3   r4   method   s    
z&Rolling._reduce_method.<locals>.methodrS   )N)getattrr   
bottleneckrF   "_ROLLING_REDUCE_DOCSTRING_TEMPLATEr<   __doc__)rS   rT   rU   r\   r3   rY   r4   _reduce_method   s    
zRolling._reduce_methodc                 K  s@   | j f ddi|| jddj| jjdd }|r<| jj|_|S )NrV   FrV   )copy)sumcountZastyper   dtyperC   )r0   rV   rX   resultr3   r3   r4   _mean   s     
zRolling._meanmeanr]   argmaxargminmaxminr/      re   r   stdvarmedianbool | NonerV   r'   c                 C  s
   t  d S rK   )NotImplementedErrorr0   rV   r3   r3   r4   _counts   s    zRolling._countsc                 C  s*   |  |}| j|d}|| jk}||S Nrc   )r   rw   r   where)r0   rV   Zrolling_countZenough_periodsr3   r3   r4   rf      s    

zRolling.countrf   Tz_T | Mapping[Any, _T]z	_T | Noneboolzlist[_T])argr)   allow_defaultallow_allsamer'   c                   s   t  r\|r$ fdd| jD S | jD ]}| kr*td| dq* fdd| jD S |rl g| j S | jdkr| gS td| j dd S )	Nc                   s   g | ]}  |qS r3   getrM   r{   r)   r3   r4   r>      s     z,Rolling._mapping_to_list.<locals>.<listcomp>zArgument has no dimension key .c                   s   g | ]} | qS r3   r3   rM   )r{   r3   r4   r>      s     ro   z"Mapping argument is necessary for z
d-rolling.)r   is_dict_liker    KeyErrorrR   r,   )r0   r{   r)   r|   r}   r1   r3   r   r4   r-      s    


zRolling._mapping_to_listc                 C  s   |d krt dd}|S NTr(   r   rv   r3   r3   r4   r      s    
zRolling._get_keep_attrs)NF)N)N)NTT) rF   
__module____qualname__ra   	__slots___attributesr5   rI   rP   propertyrR   rb   ri   r`   r<   r   NINFrk   INFrl   rm   rn   r/   re   rj   rp   rq   rr   rw   rf   r-   r   r3   r3   r3   r4   r   ;   s@   
  0 




   r   c                	      s   e Zd ZdZd'dddddd	 fd
dZddddZddejdfdddddddddZddejdfddddddddddZ	d(dddddddZ
ddd d!d"Zd#d$ Zd%d& Z  ZS ))DataArrayRolling)window_labelsNFr   r!   r"   r#   r$   r%   c                   s*   t  j||||d | j| jd  | _dS )a!  
        Moving window object for DataArray.
        You should use DataArray.rolling() method to construct this object
        instead of the class constructor.

        Parameters
        ----------
        obj : DataArray
            Object to window.
        windows : mapping of hashable to int
            A mapping from the name of the dimension to create the rolling
            exponential window along (e.g. `time`) to the size of the moving window.
        min_periods : int, default: None
            Minimum number of observations in window required to have a value
            (otherwise result is NA). The default, None, is equivalent to
            setting min_periods equal to the size of the window.
        center : bool, default: False
            Set the labels at the center of the window.

        Returns
        -------
        rolling : type of input argument

        See Also
        --------
        xarray.DataArray.rolling
        xarray.DataArray.groupby
        xarray.Dataset.rolling
        xarray.Dataset.groupby
        )r   r   r   N)superr5   r   r    r   )r0   r   r&   r   r   rE   r3   r4   r5      s    %zDataArrayRolling.__init__z%Iterator[tuple[DataArray, DataArray]]r7   c                 c  s   | j dkrtd| jd }t| jd }| jd r@|d d nd}t|| jj	| | }|| }d|d || < t
| j||D ]H\}}}| j|t||i}	|	j|gd}
|	|
| jk}	||	fV  qd S )Nro   z)__iter__ is only supported for 1d-rollingr      )r    )rR   r,   r    rJ   r   r   npZaranger   rL   rD   r   iselslicerf   ry   r   )r0   Zdim0Zwindow0offsetZstopsZstartslabelstartstopr   countsr3   r3   r4   __iter__  s    

zDataArrayRolling.__iter__ro   (Hashable | Mapping[Any, Hashable] | Noneint | Mapping[Any, int]r   rs   r   
window_dimstride
fill_valuerV   window_dim_kwargsr'   c                 K  s   | j | jf||||d|S )aG  
        Convert this rolling object to xr.DataArray,
        where the window dimension is stacked as a new dimension

        Parameters
        ----------
        window_dim : Hashable or dict-like to Hashable, optional
            A mapping from dimension name to the new window dimension names.
        stride : int or mapping of int, default: 1
            Size of stride for the rolling window.
        fill_value : default: dtypes.NA
            Filling value to match the dimension size.
        keep_attrs : bool, default: None
            If True, the attributes (``attrs``) will be copied from the original
            object to the new one. If False, the new object will be returned
            without attributes. If None uses the global default.
        **window_dim_kwargs : Hashable, optional
            The keyword arguments form of ``window_dim`` {dim: new_name, ...}.

        Returns
        -------
        DataArray that is a view of the original array. The returned array is
        not writeable.

        Examples
        --------
        >>> da = xr.DataArray(np.arange(8).reshape(2, 4), dims=("a", "b"))

        >>> rolling = da.rolling(b=3)
        >>> rolling.construct("window_dim")
        <xarray.DataArray (a: 2, b: 4, window_dim: 3)>
        array([[[nan, nan,  0.],
                [nan,  0.,  1.],
                [ 0.,  1.,  2.],
                [ 1.,  2.,  3.]],
        <BLANKLINE>
               [[nan, nan,  4.],
                [nan,  4.,  5.],
                [ 4.,  5.,  6.],
                [ 5.,  6.,  7.]]])
        Dimensions without coordinates: a, b, window_dim

        >>> rolling = da.rolling(b=3, center=True)
        >>> rolling.construct("window_dim")
        <xarray.DataArray (a: 2, b: 4, window_dim: 3)>
        array([[[nan,  0.,  1.],
                [ 0.,  1.,  2.],
                [ 1.,  2.,  3.],
                [ 2.,  3., nan]],
        <BLANKLINE>
               [[nan,  4.,  5.],
                [ 4.,  5.,  6.],
                [ 5.,  6.,  7.],
                [ 6.,  7., nan]]])
        Dimensions without coordinates: a, b, window_dim

        )r   r   r   rV   )
_constructr   )r0   r   r   r   rV   r   r3   r3   r4   	construct#  s    BzDataArrayRolling.construct)r   r   r   r   rV   r   r'   c                   s   ddl m} | |}|d krFt dkr2td fdd| jD }| j|ddd}| j|dd	}	|jj| j| j	|| j
|d
}
|r|jni }||
|jt| |j||jd}|dd t| j|	D S )Nr   r   <Either window_dim or window_dim_kwargs need to be specified.c                   s   i | ]}| t | qS r3   r6   rM   r   r3   r4   
<dictcomp>  s      z/DataArrayRolling._construct.<locals>.<dictcomp>Fr|   r}   ro   r(   )r   )dimscoordsrC   rS   c                 S  s   i | ]\}}|t d d |qS rK   r   r=   r1   sr3   r3   r4   r     s      )xarray.core.dataarrayr   r   rQ   r,   r    r-   variableZrolling_windowr   r   rC   r   tupler   rS   r   rD   )r0   r   r   r   r   rV   r   r   window_dimsstridesr   rC   rh   r3   r   r4   r   n  s<    	
      zDataArrayRolling._constructr   funcrV   rX   r'   c           
        s     |} fdd jD }|dtj}|tjk	rD j|}n j} j||||d}|j|ft	|
 |d|} jdd}	||	 jkS )a  Reduce the items in this group by applying `func` along some
        dimension(s).

        Parameters
        ----------
        func : callable
            Function which can be called in the form
            `func(x, **kwargs)` to return the result of collapsing an
            np.ndarray over an the rolling dimension.
        keep_attrs : bool, default: None
            If True, the attributes (``attrs``) will be copied from the original
            object to the new one. If False, the new object will be returned
            without attributes. If None uses the global default.
        **kwargs : dict
            Additional keyword arguments passed on to `func`.

        Returns
        -------
        reduced : DataArray
            Array with summarized data.

        Examples
        --------
        >>> da = xr.DataArray(np.arange(8).reshape(2, 4), dims=("a", "b"))
        >>> rolling = da.rolling(b=3)
        >>> rolling.construct("window_dim")
        <xarray.DataArray (a: 2, b: 4, window_dim: 3)>
        array([[[nan, nan,  0.],
                [nan,  0.,  1.],
                [ 0.,  1.,  2.],
                [ 1.,  2.,  3.]],
        <BLANKLINE>
               [[nan, nan,  4.],
                [nan,  4.,  5.],
                [ 4.,  5.,  6.],
                [ 5.,  6.,  7.]]])
        Dimensions without coordinates: a, b, window_dim

        >>> rolling.reduce(np.sum)
        <xarray.DataArray (a: 2, b: 4)>
        array([[nan, nan,  3.,  6.],
               [nan, nan, 15., 18.]])
        Dimensions without coordinates: a, b

        >>> rolling = da.rolling(b=3, min_periods=1)
        >>> rolling.reduce(np.nansum)
        <xarray.DataArray (a: 2, b: 4)>
        array([[ 0.,  1.,  3.,  6.],
               [ 4.,  9., 15., 18.]])
        Dimensions without coordinates: a, b
        c                   s$   i | ]}|t  jjd | qS Z_rolling_dim_r   Zget_temp_dimnamer   r   rM   rN   r3   r4   r     s    z+DataArrayRolling.reduce.<locals>.<dictcomp>rT   )rV   r   )r    rV   Frc   )r   r    popr   NAr   rT   r   reducelistvaluesrw   ry   r   )
r0   r   rV   rX   rolling_dimrT   r   r&   rh   r   r3   rN   r4   r     s0    7


   
 zDataArrayRolling.reducert   c                   sx    fdd j D } jj|djdd t j  jD  fddt j D dj|d|djt	|
 d|d	}|S )
z1Number of non-nan entries in each rolling window.c                   s$   i | ]}|t  jjd | qS r   r   rM   rN   r3   r4   r     s    z,DataArrayRolling._counts.<locals>.<dictcomp>rc   c                 S  s   i | ]\}}||qS r3   r3   )r=   r1   r2   r3   r3   r4   r     s      c                   s   i | ]\}}| j | qS r3   r   r=   ir1   rN   r3   r4   r     s      r   F)r   rV   )r    skipnarV   )r    r   ZnotnullZrollingrD   r   	enumerater   re   r   r   )r0   rV   r   r   r3   rN   r4   rw     s"    
	  
  	zDataArrayRolling._countsc                 K  sb  ddl m} | jd k	r&| jdkr&d}n| j}| j| jd }| jj}| jd rt|j	r| j
d d  d }| j
d d d }	td f| t|	|	| jj|  f }
n0| j
d  d d }td f| t| d f }
|j| jd d| fidd}t|j	rtdn||j	| j
d ||d}| jd r8||
 }|rF| jjni }||| jj|| jjd	S )
Nr   r   ro   r   Zconstant)modezshould not be reachable)r   	min_countaxis)rC   rS   )r   r   r   r   Zget_axis_numr    r   r   r   datar   r   shapepadAssertionErrorrC   r   rS   )r0   r   rV   rX   r   r   r   Zpaddedshiftr   Zvalidr   rC   r3   r3   r4   _bottleneck_reduce  s8    


   z#DataArrayRolling._bottleneck_reducec                 K  s   d|kr(t jd| j dtdd |d= td rd|d k	rdt| jjsd| jdkrd| j	|fd|i|S |rz|| | 
|d	S |d k	r|tjkrtj| jjd
d}n|tjkrtj| jjd
d}|dd |d| | j|fd|i|S )Nr    z7Reductions are applied along the rolling dimension(s) 'zA'. Passing the 'dim' kwarg to reduction operations has no effect.   )
stacklevelZuse_bottleneckro   rV   rc   T)Zmax_for_int)Zmin_for_intr   FrT   )warningswarnr    DeprecationWarningr   r   r   r   rR   r   r   r   r   Zget_pos_infinityrg   r   Zget_neg_infinity
setdefaultr   )r0   rZ   r[   rU   rV   rT   rX   r3   r3   r4   rW   &  s@    	
	

z,DataArrayRolling._numpy_or_bottleneck_reduce)NF)N)rF   r   r   r   r5   r   r   r   r   r   r   rw   r   rW   __classcell__r3   r3   r   r4   r      s(     *N) P*r   r   c                      s   e Zd ZdZd!dddddd	 fd
dZdd Zd"dddddddZdddddZdd Zdde	j
dfddddddddd Z  ZS )#DatasetRolling)rollingsNFr   r!   r"   r#   r$   r%   c                   s   t  ||| t fdd jD r4t ji  _ jj D ]r\}}g i  }}t	 jD ]*\}}	|	|j
krb||	  j| ||	< qb|rFfdd|D }
t||
|| j|< qFdS )a:  
        Moving window object for Dataset.
        You should use Dataset.rolling() method to construct this object
        instead of the class constructor.

        Parameters
        ----------
        obj : Dataset
            Object to window.
        windows : mapping of hashable to int
            A mapping from the name of the dimension to create the rolling
            exponential window along (e.g. `time`) to the size of the moving window.
        min_periods : int, default: None
            Minimum number of observations in window required to have a value
            (otherwise result is NA). The default, None, is equivalent to
            setting min_periods equal to the size of the window.
        center : bool or mapping of hashable to bool, default: False
            Set the labels at the center of the window.

        Returns
        -------
        rolling : type of input argument

        See Also
        --------
        xarray.Dataset.rolling
        xarray.DataArray.rolling
        xarray.Dataset.groupby
        xarray.DataArray.groupby
        c                 3  s   | ]}| j jkV  qd S rK   r   r   rM   rN   r3   r4   rO   {  s     z*DatasetRolling.__init__.<locals>.<genexpr>c                   s   i | ]}| | qS r3   r3   rM   r&   r3   r4   r     s      z+DatasetRolling.__init__.<locals>.<dictcomp>N)r   r5   anyr    r   r   r   	data_varsr*   r   r   r+   r   r   )r0   r   r&   r   r   keydar   r   r1   r2   r   )r0   r&   r4   r5   U  s    %



zDatasetRolling.__init__c                   s   ddl m} | |}i }| jj D ]`\} t fdd| jD rf|| j| fd|i|||< q&| j| 	 ||< |s&i || _
q&|r| jj
ni }||| jj|dS )Nr   r   c                 3  s   | ]}| j kV  qd S rK   r   rM   r   r3   r4   rO     s     z9DatasetRolling._dataset_implementation.<locals>.<genexpr>rV   r   rC   )xarray.core.datasetr   r   r   r   r*   r   r    r   rd   rC   r   )r0   r   rV   rX   r   reducedr   rC   r3   r   r4   _dataset_implementation  s    
 z&DatasetRolling._dataset_implementationr   rs   r   r   r   c                 K  s"   | j tjtj|dfd|i|S )a  Reduce the items in this group by applying `func` along some
        dimension(s).

        Parameters
        ----------
        func : callable
            Function which can be called in the form
            `func(x, **kwargs)` to return the result of collapsing an
            np.ndarray over an the rolling dimension.
        keep_attrs : bool, default: None
            If True, the attributes (``attrs``) will be copied from the original
            object to the new one. If False, the new object will be returned
            without attributes. If None uses the global default.
        **kwargs : dict
            Additional keyword arguments passed on to `func`.

        Returns
        -------
        reduced : DataArray
            Array with summarized data.
        r   rV   )r   	functoolspartialr   r   )r0   r   rV   rX   r3   r3   r4   r     s    zDatasetRolling.reducert   c                 C  s   | j tj|dS rx   )r   r   rw   rv   r3   r3   r4   rw     s     zDatasetRolling._countsc                 K  s&   | j tjtj|||dfd|i|S )N)rZ   r[   rU   rV   )r   r   r   r   rW   )r0   rZ   r[   rU   rV   rX   r3   r3   r4   rW     s    z*DatasetRolling._numpy_or_bottleneck_reducero   r   r   r   r   c                   s>  ddl m} | |}|dkrFtdkr2tdfdd| jD }| j|ddd| j|d	d
i }| jj	 D ]\}  fdd| jD }	|	r fddt
| jD }
 fddt
| jD }| j| j|
|||d||< n  ||< |sti || _qt|r| jjni }||| jj|ddd t| jD S )a  
        Convert this rolling object to xr.Dataset,
        where the window dimension is stacked as a new dimension

        Parameters
        ----------
        window_dim : str or mapping, optional
            A mapping from dimension name to the new window dimension names.
            Just a string can be used for 1d-rolling.
        stride : int, optional
            size of stride for the rolling window.
        fill_value : Any, default: dtypes.NA
            Filling value to match the dimension size.
        **window_dim_kwargs : {dim: new_name, ...}, optional
            The keyword arguments form of ``window_dim``.

        Returns
        -------
        Dataset with variables converted from rolling object.
        r   r   Nr   c                   s   i | ]}| t | qS r3   r   rM   r   r3   r4   r     s      z,DatasetRolling.construct.<locals>.<dictcomp>Fr   ro   r(   c                   s   g | ]}| j kr|qS r3   r   rM   r   r3   r4   r>     s     
 z,DatasetRolling.construct.<locals>.<listcomp>c                   s$   i | ]\}}| j kr|| qS r3   r   r   )r   r   r3   r4   r     s     
  c                   s$   i | ]\}}| j kr|| qS r3   r   r   )r   r   r3   r4   r     s     
  )r   r   r   rV   r   c                 S  s   i | ]\}}|t d d |qS rK   r   r   r3   r3   r4   r     s      )r   r   r   rQ   r,   r    r-   r   r   r*   r   r   r   rd   rC   r   r   rD   )r0   r   r   r   rV   r   r   Zdatasetr   r   ZwistrC   r3   )r   r   r   r   r4   r     sB    
  
zDatasetRolling.construct)NF)N)rF   r   r   r   r5   r   r   rw   rW   r   r   r   r   r3   r3   r   r4   r   R  s     6 r   r   c                   @  s`   e Zd ZU dZdZdZded< ddddd	d
dddZdd ZddddZ	dddddZ
dS )CoarsenzoA object that implements the coarsen.

    See Also
    --------
    Dataset.coarsen
    DataArray.coarsen
    )r   boundary
coord_funcr&   sidetrim_excess)r&   r   r   r   r   r!   r   z'SideOptions | Mapping[Any, SideOptions]z-str | Callable | Mapping[Any, str | Callable]r$   )r   r&   r   r   r   r'   c                   s   |_ |_|_|_fdd| D }|rNtd|dj jj dt	 sn fddj j
D  j jD ]}| krvtj |< qv _dS )	a*  
        Moving window object.

        Parameters
        ----------
        obj : Dataset or DataArray
            Object to window.
        windows : mapping of hashable to int
            A mapping from the name of the dimension to create the rolling
            exponential window along (e.g. `time`) to the size of the moving window.
        boundary : {"exact", "trim", "pad"}
            If 'exact', a ValueError will be raised if dimension size is not a
            multiple of window size. If 'trim', the excess indexes are trimmed.
            If 'pad', NA will be padded.
        side : 'left' or 'right' or mapping from dimension to 'left' or 'right'
        coord_func : function (name) or mapping from coordinate name to function (name).

        Returns
        -------
        coarsen
        c                   s   g | ]}| j jkr|qS r3   r   r=   r    rN   r3   r4   r>   R  s      z$Coarsen.__init__.<locals>.<listcomp>zDimensions z not found in r   c                   s   i | ]
}| qS r3   r3   rM   )r   r3   r4   r   X  s      z$Coarsen.__init__.<locals>.<dictcomp>N)r   r&   r   r   keysr,   rE   rF   r   r   r   r   r   rj   r   )r0   r   r&   r   r   r   Zabsent_dimsr;   r3   )r   r0   r4   r5   0  s    
zCoarsen.__init__c                 C  s   |d krt dd}|S r   r   rv   r3   r3   r4   r   ^  s    
zCoarsen._get_keep_attrsr6   r7   c                   s,    fdd j D }dj jjd|dS )z-provide a nice str repr of our coarsen objectc                   s0   g | ](}t  |d d k	r| dt  | qS )Nz->)r^   )r=   r9   rN   r3   r4   r>   g  s   z$Coarsen.__repr__.<locals>.<listcomp>r?   r@   rA   )r   r<   rE   rF   rG   rH   r3   rN   r4   rI   d  s    
 zCoarsen.__repr__Nc                   s  ddl m} ddlm} t|ds0tdtdd  D }|rXtd| |d	krjtd
d}t	t	 j
 }|rtd| t	 j
t	 }|rtd| | }	t j|rЈ j }
n j}
|r|
jni |	_|
j D ]\}ttjfddtjD  }|jkrp fddD }| j j\}}|r\jni }|||f|	|< q|	|< qt	t	 jj@ t	 jjB }|	|}t j|r j|S |S d	S )a  
        Convert this Coarsen object to a DataArray or Dataset,
        where the coarsening dimension is split or reshaped to two
        new dimensions.

        Parameters
        ----------
        window_dim: mapping
            A mapping from existing dimension name to new dimension names.
            The size of the second dimension will be the length of the
            coarsening window.
        keep_attrs: bool, optional
            Preserve attributes if True
        **window_dim_kwargs : {dim: new_name, ...}
            The keyword arguments form of ``window_dim``.

        Returns
        -------
        Dataset or DataArray with reshaped dimensions

        Examples
        --------
        >>> da = xr.DataArray(np.arange(24), dims="time")
        >>> da.coarsen(time=12).construct(time=("year", "month"))
        <xarray.DataArray (year: 2, month: 12)>
        array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11],
               [12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]])
        Dimensions without coordinates: year, month

        See Also
        --------
        DataArrayRolling.construct
        DatasetRolling.construct
        r   r   r   Coarsen.constructr   c                 s  s,   | ]$\}}t |d ks t|tr|V  qdS )r   N)rQ   
isinstancer6   )r=   winr   r3   r3   r4   rO     s    
z$Coarsen.construct.<locals>.<genexpr>zTPlease provide exactly two dimension names for the following coarsening dimensions: NTr(   zI'window_dim' must contain entries for all dimensions to coarsen. Missing z='window_dim' includes dimensions that will not be coarsened: c                   s   g | ]}  ||gqS r3   r~   r   )r   r3   r4   r>     s     z%Coarsen.construct.<locals>.<listcomp>c                   s"   i | ]}|j kr| j| qS r3   )r   r&   )r=   r2   )r0   rq   r3   r4   r     s     
  z%Coarsen.construct.<locals>.<dictcomp>)r   r   r   r   r   r,   r   r*   r   setr&   r   r   Z_to_temp_datasetrC   	variables	itertoolschainr   r   Zcoarsen_reshaper   r   r   Z
set_coordsZ_from_temp_dataset)r0   r   rV   r   r   r   Zbad_new_dimsZmissing_dimsZextra_windowsZreshapedr   r   Zreshaped_dimsr&   Zreshaped_var_rC   Zshould_be_coordsrh   r3   )r0   rq   r   r4   r   p  sh    )  


r   )NN)rF   r   r   ra   r   r   __annotations__r5   r   rI   r   r3   r3   r3   r4   r     s   
.  r   c                   @  sB   e Zd ZdZdZedddddddd	ZdddddddZd
S )DataArrayCoarsenr3   r8   Fr   rz   zCallable[..., DataArray]r   include_skipnanumeric_onlyr'   c                   s,   i }|rd|d< d	dddd fdd}|S )
r
        Return a wrapped function for injecting reduction methods.
        see ops.inject_reduce_methods
        Nr   r   rs   r   r0   rV   r'   c                   s   ddl m}  |} jjj j j j|f|}i } jj	
 D ]h\}}| jjkrd|||< qFt fdd|jD r|jj j j|  j j|f|||< qF|||< qF|| jj| jjdS )Nr   r   c                 3  s   | ]}| j kV  qd S rK   r   rM   rN   r3   r4   rO     s     zHDataArrayCoarsen._reduce_method.<locals>.wrapped_func.<locals>.<genexpr>)r   r   rS   )r   r   r   r   r   coarsenr&   r   r   r   r*   rS   r   r   r   )r0   rV   rX   r   r   r   r;   r:   r   rN   r4   wrapped_func  s@    
    

	
   z5DataArrayCoarsen._reduce_method.<locals>.wrapped_func)Nr3   clsr   r   r   rX   r   r3   r   r4   rb     s     zDataArrayCoarsen._reduce_methodNrs   r   )r   rV   r'   c                 K  s   |  |}|| fd|i|S )a  Reduce the items in this group by applying `func` along some
        dimension(s).

        Parameters
        ----------
        func : callable
            Function which can be called in the form `func(x, axis, **kwargs)`
            to return the result of collapsing an np.ndarray over the coarsening
            dimensions.  It must be possible to provide the `axis` argument
            with a tuple of integers.
        keep_attrs : bool, default: None
            If True, the attributes (``attrs``) will be copied from the original
            object to the new one. If False, the new object will be returned
            without attributes. If None uses the global default.
        **kwargs : dict
            Additional keyword arguments passed on to `func`.

        Returns
        -------
        reduced : DataArray
            Array with summarized data.

        Examples
        --------
        >>> da = xr.DataArray(np.arange(8).reshape(2, 4), dims=("a", "b"))
        >>> coarsen = da.coarsen(b=2)
        >>> coarsen.reduce(np.sum)
        <xarray.DataArray (a: 2, b: 2)>
        array([[ 1,  5],
               [ 9, 13]])
        Dimensions without coordinates: a, b
        rV   rb   r0   r   rV   rX   r   r3   r3   r4   r     s    #
zDataArrayCoarsen.reduce)FF)NrF   r   r   r   Z_reduce_extra_args_docstringclassmethodrb   r   r3   r3   r3   r4   r     s      , r   c                   @  s@   e Zd ZdZdZedddddddd	ZddddddZd
S )DatasetCoarsenr3   r8   Fr   rz   zCallable[..., Dataset]r   c                   s,   i }|rd|d< d	dddd fdd}|S )
r   Nr   r  rs   r   r   c                   s   ddl m} | |}|r$| jj}ni }i }| jj D ]0\}}|jj| j	 | j
| jfd|i|||< q8i }| jj D ]6\}	}
|
jj| j	| j|	 | j
| jfd|i|||	< qz||||dS )Nr   r   rV   r   )r   r   r   r   rC   r   r*   r   r   r&   r   r   r   r   )r0   rV   rX   r   rC   r   r   r   r   r;   r:   r   r3   r4   r   D  s<    

		z3DatasetCoarsen._reduce_method.<locals>.wrapped_func)Nr3   r   r3   r   r4   rb   8  s     &zDatasetCoarsen._reduce_methodNr   )r   r'   c                 K  s   |  |}|| fd|i|S )an  Reduce the items in this group by applying `func` along some
        dimension(s).

        Parameters
        ----------
        func : callable
            Function which can be called in the form `func(x, axis, **kwargs)`
            to return the result of collapsing an np.ndarray over the coarsening
            dimensions.  It must be possible to provide the `axis` argument with
            a tuple of integers.
        keep_attrs : bool, default: None
            If True, the attributes (``attrs``) will be copied from the original
            object to the new one. If False, the new object will be returned
            without attributes. If None uses the global default.
        **kwargs : dict
            Additional keyword arguments passed on to `func`.

        Returns
        -------
        reduced : Dataset
            Arrays with summarized data.
        rV   r   r   r3   r3   r4   r   l  s    
zDatasetCoarsen.reduce)FF)Nr   r3   r3   r3   r4   r  3  s      3r  )1
__future__r   r   r   r.   r   typingr   r   r   r   r   r   r	   r
   Znumpyr   Zxarray.corer   r   r   Zxarray.core.arithmeticr   Zxarray.core.optionsr   r   Zxarray.core.pycompatr   Zxarray.core.typesr   r   r   Zxarray.core.utilsr   r_   ImportErrorr   r   r   r   Z
RollingKeyr   r`   r   r   r   r   r   r  r3   r3   r3   r4   <module>   sB   (
 )  q K @X