
    dJ                       d dl mZ d dlmZmZmZ d dlmZ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mZ d dlmZmZ d d	lmZ d d
lmZmZ e	d         ZdZdZdZ erd dl!m"Z" d dl#m$Z$  G d dee                   Z% G d de%d                   Z& G d de%d                   Z'd Z( e(e&d            e(e'd           dS )    )annotations)HashableIterableSequence)TYPE_CHECKINGGenericLiteralcastN)	ArrayLike)duck_array_opsutils)align	broadcast)apply_ufuncdot)is_duck_dask_array)DimsT_Xarray)linearinterpolated_inverted_cdfhazenweibullmedian_unbiasednormal_unbiaseda  
    Reduce this {cls}'s data by a weighted ``{fcn}`` along some dimension(s).

    Parameters
    ----------
    dim : Hashable or Iterable of Hashable, optional
        Dimension(s) over which to apply the weighted ``{fcn}``.
    skipna : bool or None, optional
        If True, skip missing values (as marked by NaN). By default, only
        skips missing values for float dtypes; other dtypes either do not
        have a sentinel missing value (int) or skipna=True has not been
        implemented (object, datetime64 or timedelta64).
    keep_attrs : bool or None, optional
        If True, the attributes (``attrs``) will be copied from the original
        object to the new one.  If False (default), the new object will be
        returned without attributes.

    Returns
    -------
    reduced : {cls}
        New {cls} object with weighted ``{fcn}`` applied to its data and
        the indicated dimension(s) removed.

    Notes
    -----
        Returns {on_zero} if the ``weights`` sum to 0.0 along the reduced
        dimension(s).
    a)  
    Calculate the sum of weights, accounting for missing values in the data.

    Parameters
    ----------
    dim : str or sequence of str, optional
        Dimension(s) over which to sum the weights.
    keep_attrs : bool, optional
        If True, the attributes (``attrs``) will be copied from the original
        object to the new one.  If False (default), the new object will be
        returned without attributes.

    Returns
    -------
    reduced : {cls}
        New {cls} object with the sum of the weights over the given dimension.
    uT	  
    Apply a weighted ``quantile`` to this {cls}'s data along some dimension(s).

    Weights are interpreted as *sampling weights* (or probability weights) and
    describe how a sample is scaled to the whole population [1]_. There are
    other possible interpretations for weights, *precision weights* describing the
    precision of observations, or *frequency weights* counting the number of identical
    observations, however, they are not implemented here.

    For compatibility with NumPy's non-weighted ``quantile`` (which is used by
    ``DataArray.quantile`` and ``Dataset.quantile``), the only interpolation
    method supported by this weighted version corresponds to the default "linear"
    option of ``numpy.quantile``. This is "Type 7" option, described in Hyndman
    and Fan (1996) [2]_. The implementation is largely inspired by a blog post
    from A. Akinshin's [3]_.

    Parameters
    ----------
    q : float or sequence of float
        Quantile to compute, which must be between 0 and 1 inclusive.
    dim : str or sequence of str, optional
        Dimension(s) over which to apply the weighted ``quantile``.
    skipna : bool, optional
        If True, skip missing values (as marked by NaN). By default, only
        skips missing values for float dtypes; other dtypes either do not
        have a sentinel missing value (int) or skipna=True has not been
        implemented (object, datetime64 or timedelta64).
    keep_attrs : bool, optional
        If True, the attributes (``attrs``) will be copied from the original
        object to the new one.  If False (default), the new object will be
        returned without attributes.

    Returns
    -------
    quantiles : {cls}
        New {cls} object with weighted ``quantile`` applied to its data and
        the indicated dimension(s) removed.

    See Also
    --------
    numpy.nanquantile, pandas.Series.quantile, Dataset.quantile, DataArray.quantile

    Notes
    -----
    Returns NaN if the ``weights`` sum to 0.0 along the reduced
    dimension(s).

    References
    ----------
    .. [1] https://notstatschat.rbind.io/2020/08/04/weights-in-statistics/
    .. [2] Hyndman, R. J. & Fan, Y. (1996). Sample Quantiles in Statistical Packages.
           The American Statistician, 50(4), 361–365. https://doi.org/10.2307/2684934
    .. [3] https://aakinshin.net/posts/weighted-quantiles
    	DataArray)Datasetc                      e Zd ZdZdZd)d	Zd*dZe	 	 d+d,d            Zd-d.dZ		 	 d+d/dZ
	 	 d+d/dZ	 	 d+d/dZ	 	 d+d/dZ	 	 d+d/dZ	 	 d+d0dZd Z	 	 d+d1dZ	 	 	 d2d3dZ	 	 	 d2d3dZ	 	 	 d2d3d Z	 	 	 d2d3d!Z	 	 	 d2d3d"Zddd#d$d4d&Zd5d(ZdS )6WeightedzAn object that implements weighted operations.

    You should create a Weighted object by using the ``DataArray.weighted`` or
    ``Dataset.weighted`` methods.

    See Also
    --------
    Dataset.weighted
    DataArray.weighted
    )objweightsr    r   r!   r   returnNonec                (   ddl m} t          ||          st          d          d }t	          |j                  r7|                    |j                            ||j                  d          }n ||j                   || _	        || _
        dS )	aH  
        Create a Weighted object

        Parameters
        ----------
        obj : DataArray or Dataset
            Object over which the weighted reduction operation is applied.
        weights : DataArray
            An array of weights associated with the values in the obj.
            Each value in the obj contributes to the reduction operation
            according to its associated weight.

        Notes
        -----
        ``weights`` must be a ``DataArray`` and cannot contain missing values.
        Missing values can be replaced by ``weights.fillna(0)``.
        r   r   z`weights` must be a DataArrayc                p    t          j        |                                           rt          d          | S )Nz_`weights` cannot contain missing values. Missing values can be replaced by `weights.fillna(0)`.)r   isnullany
ValueError)ws    4lib/python3.11/site-packages/xarray/core/weighted.py_weight_checkz(Weighted.__init__.<locals>._weight_check   s@    $Q''++--  M   H    dtypeF)datadeepN)xarray.core.dataarrayr   
isinstancer(   r   r/   copy
map_blocksr.   r    r!   )selfr    r!   r   r+   s        r*   __init__zWeighted.__init__   s    & 	433333'9-- 	><===	 	 	 gl++ 	(ll\,,]'-,PP #  GG M',''' ")r,   dimr   c                N   t          |t                    st          |t                    s|r|gng }nt          |          }t	          |          t	          | j        j                  z
  t	          | j        j                  z
  }|rt          | j	        j
         d|           dS )z*raise an error if any dimension is missingz" does not contain the dimensions: N)r2   strr   listsetr    dimsr!   r(   	__class____name__)r5   r7   r<   missing_dimss       r*   
_check_dimzWeighted._check_dim   s     c3 	z#x'@'@ 	'C55RDD99D4yy3tx}#5#55DL<M8N8NN 	>*\\l\\  	 	r,   Ndaskipnabool | Nonec                |    |d}|s|#| j         j        dv r|                     d          } t          | ||          S )zgreduce using dot; equivalent to (da * weights).sum(dim, skipna)

        for internal use only
        N.cfO        )r<   )r.   kindfillnar   )rA   r!   r7   rB   s       r*   _reducezWeighted._reduce   sP     ;C  	 fn%)?)?3B 2wS))))r,   c                6   |                                 }| j        j        t          k    r8|                     |t          j        | j        t                    |d          }n|                     || j        |d          }|dk    }|                    |          S )z;Calculate the sum of weights, accounting for missing valuesr-   Fr7   rB   rF   )	notnullr!   r.   boolrI   r   astypeintwhere)r5   rA   r7   masksum_of_weightsvalid_weightss         r*   _sum_of_weightszWeighted._sum_of_weights   s     zz|| <%%!\\%dl#>>>	 *  NN "\\$#e\TTN '#-##M222r,   c                    ||                     | j                                      |          z
  }|                     |dz  | j        ||          S )zLReduce a DataArray by a weighted ``sum_of_squares`` along some dimension(s).r7      rK   )weightedr!   meanrI   )r5   rA   r7   rB   demeaneds        r*   _sum_of_squareszWeighted._sum_of_squares   sM     DL116636???||Xq[4<S|PPPr,   c                >    |                      || j        ||          S )zAReduce a DataArray by a weighted ``sum`` along some dimension(s).rK   )rI   r!   r5   rA   r7   rB   s       r*   _weighted_sumzWeighted._weighted_sum
  s      ||B#f|EEEr,   c                j    |                      |||          }|                     ||          }||z  S )zBReduce a DataArray by a weighted ``mean`` along some dimension(s).rK   rV   )r^   rT   )r5   rA   r7   rB   weighted_sumrR   s         r*   _weighted_meanzWeighted._weighted_mean  sA     ))"#f)EE--bc-::n,,r,   c                j    |                      |||          }|                     ||          }||z  S )zAReduce a DataArray by a weighted ``var`` along some dimension(s).rK   rV   )r[   rT   )r5   rA   r7   rB   sum_of_squaresrR   s         r*   _weighted_varzWeighted._weighted_var"  sA     --bc&-II--bc-::..r,   c           
     p    t          dt          j        |                     |||                              S )zAReduce a DataArray by a weighted ``std`` along some dimension(s).r   )r
   npsqrtrd   r]   s       r*   _weighted_stdzWeighted._weighted_std0  s0     K););BV)L)L!M!MNNNr,   qr   c                   d d	 d!d"fd}||j         j        dv rd}t          j        t          j        |t          j                            }|j        dk    rt          d          t          j        |dk     |dk    z            rt          d          ||j	        }t          j        |          r|g}t          t          |          }t          || j        d          \  }}t!          ||          \  }}t#          |||||gdggt          j        gt%          dt'          |          i          dd||d
  
        }|                    dd          }|                    |                                          }|S )#zEApply a weighted ``quantile`` to a DataArray along some dimension(s).nfloatri   
np.ndarraymethodQUANTILE_METHODSr"   c                   |dk    r| dz
  |z  dz   }na|dk    r| |z  }nU|dk    r	| |z  dz   }nF|dk    r	| dz   |z  }n7|dk    r| dz   |z  dz   }n%|d	k    r| d
z   |z  dz   }nt          d| d          |                    d|           S )z#Return the interpolation parameter.r      r   r   g      ?r   r   gUUUUUU?r   g      ?g      ?zInvalid method: .)r(   clip)rk   ri   rn   hs       r*   _get_hz+Weighted._weighted_quantile.<locals>._get_hC  s     !!UaK!O666E7""ECK9$$UaK,,,Y!Oe+,,,Y!Oe+ !=F!=!=!=>>>66!Q<<r,   r   r/   r!   rB   rM   c                   t          j        |           }|r| }| |         } ||         }n8|                                r$t          j        |j        t           j                  S |dk    }| |         } ||         }| j        }|dk    r$t          j        |j        t           j                  S |                                dz  |dz                                  z  }	t          j        |           }
| |
         } ||
         }||                                z  }t          j        d|	                                          }t          j
        |          j        } |	||          }t          j        |dz
  |	z  t          j        ||	z  |                    }||	z  |z
  dz   }t          j        |          }| |z                      d          S )Nr   rW   rq   )axis)rf   isnanr'   fullsizenansumargsortappendcumsum
atleast_2dTmaximumminimumdiff)r/   r!   ri   rB   rn   is_nannot_nannonzero_weightsrk   nwsorterweights_cumrt   uvr)   ru   s                   r*   _weighted_quantile_1dz:Weighted._weighted_quantile.<locals>._weighted_quantile_1dV  s    Xd^^F /!'G}!'* /wqvrv... &lO(Do.G	AAvvwqvrv... !#wz&6&6&8&88B Z%%F<DfoG -G)Aw~~'7'788K a  "A r1f%%A 
AER<AFK)H)HIIA B
QA

A 1H>>q>)))r,   NrE   Tr-   rq   zq must be a scalar or 1dr   z q values must be between 0 and 1inner)joinquantile)output_sizesparallelized)ri   rB   )input_core_dimsoutput_core_dimsoutput_dtypesdask_gufunc_kwargsdask	vectorizekwargs.)r   )rk   rl   ri   rm   rn   ro   r"   rm   )r   )r/   rm   r!   rm   ri   rm   rB   rM   rn   ro   r"   rm   )r.   rG   rf   
atleast_1dasarrayfloat64ndimr(   r'   r<   r   	is_scalarr
   r   r   r!   r   r   dictlen	transposeassign_coordssqueeze)	r5   rA   ri   r7   rB   r   r!   resultru   s	           @r*   _weighted_quantilezWeighted._weighted_quantile:  s   	  	  	  	 0 (07	* 7	* 7	* 7	* 7	* 7	* 7	*r >bhmu44FM"*Qbj999::6A::788861q5QU#$$ 	A?@@@;'C?3 	%C 8S!! B7;;;GG,,G! #J)l^:,#*c!ff1EFFFf--
 
 
 !!*c22%%q%1199;;r,   c                     t          d          )Nz.Use `Dataset.weighted` or `DataArray.weighted`)NotImplementedErrorr5   funcr7   r   s       r*   _implementationzWeighted._implementation  s    !"RSSSr,   
keep_attrsc                <    |                      | j        ||          S )N)r7   r   )r   rT   )r5   r7   r   s      r*   rR   zWeighted.sum_of_weights  s+    
 ## cj $ 
 
 	
r,   c                >    |                      | j        |||          S N)r7   rB   r   )r   r[   r5   r7   rB   r   s       r*   rc   zWeighted.sum_of_squares  s-     ## c&Z $ 
 
 	
r,   c                >    |                      | j        |||          S r   )r   r^   r   s       r*   r|   zWeighted.sum  -     ##C: $ 
 
 	
r,   c                >    |                      | j        |||          S r   )r   ra   r   s       r*   rY   zWeighted.mean  s-     ##SJ $ 
 
 	
r,   c                >    |                      | j        |||          S r   )r   rd   r   s       r*   varzWeighted.var  r   r,   c                >    |                      | j        |||          S r   )r   rh   r   s       r*   stdzWeighted.std  r   r,   T)r7   r   rB   rM   c               @    |                      | j        ||||          S )N)ri   r7   rB   r   )r   r   )r5   ri   r7   r   rB   s        r*   r   zWeighted.quantile  s/     ###qc&Z $ 
 
 	
r,   r9   c                    | j         j        }d                    t          t          | j        j                            }| d| S )z.provide a nice str repr of our Weighted objectz, z  with weights along dimensions: )r=   r>   r   mapr9   r!   r<   )r5   klassweight_dimss      r*   __repr__zWeighted.__repr__
  sB     'iiC): ; ;<<FFFFFr,   )r    r   r!   r   r"   r#   )r7   r   )NN)
rA   r   r!   r   r7   r   rB   rC   r"   r   )N)rA   r   r7   r   r"   r   )rA   r   r7   r   rB   rC   r"   r   )
rA   r   ri   r   r7   r   rB   rC   r"   r   )r7   r   r   rC   r"   r   )NNN)r7   r   rB   rC   r   rC   r"   r   )
ri   r   r7   r   r   rC   rB   rM   r"   r   )r"   r9   )r>   
__module____qualname____doc__	__slots__r6   r@   staticmethodrI   rT   r[   r^   ra   rd   rh   r   r   rR   rc   r|   rY   r   r   r   r    r,   r*   r   r      s       	 	 #I,* ,* ,* ,*\     "	* * * * \*.3 3 3 3 34 "	
Q 
Q 
Q 
Q 
Q "	F F F F F "	- - - - -" "	/ / / / /" "	O O O O O "D D D D DLT T T
 "&
 
 
 
 
 ""&	
 
 
 
 
 ""&	
 
 
 
 
 ""&	
 
 
 
 
 ""&	
 
 
 
 
 ""&	
 
 
 
 
 "&

 

 

 

 

 

G G G G G Gr,   r   c                      e Zd ZddZdS )DataArrayWeightedr"   r   c                    |                      |           | j                                        } |j        |fd|i|}| j                            |          S Nr7   )r@   r    _to_temp_datasetr   _from_temp_dataset)r5   r   r7   r   datasets        r*   r   z!DataArrayWeighted._implementation  s[    (++--'+d666v66x**7333r,   N)r"   r   r>   r   r   r   r   r,   r*   r   r     s(        4 4 4 4 4 4r,   r   r   c                      e Zd ZddZdS )DatasetWeightedr"   r   c                V    |                      |            | j        j        |fd|i|S r   )r@   r    r   r   s       r*   r   zDatasetWeighted._implementation  s5    tx|D44c4V444r,   N)r"   r   r   r   r,   r*   r   r     s(        5 5 5 5 5 5r,   r   r   c                    t                               |          | j        _        t                              |dd          | j        _        t                              |dd          | j        _        t                              |dd          | j        _        t                              |dd          | j        _        t                              |d	d          | j	        _        t                              |          | j        _        d S )
N)clsr|   0)r   fcnon_zerorY   NaNrc   r   r   )_SUM_OF_WEIGHTS_DOCSTRINGformatrR   r   #_WEIGHTED_REDUCE_DOCSTRING_TEMPLATEr|   rY   rc   r   r   %_WEIGHTED_QUANTILE_DOCSTRING_TEMPLATEr   )r   cls_names     r*   _inject_docstringr   "  s   !:!A!Ah!A!O!OC9@@% A  CGO ;AA&% B  CH "E!K!K*C "L " "C :@@% A  CGO :@@% A  CGO AGGHGUUCLr,   ))
__future__r   collections.abcr   r   r   typingr   r   r	   r
   numpyrf   numpy.typingr   xarray.corer   r   xarray.core.alignmentr   r   xarray.core.computationr   r   xarray.core.pycompatr   xarray.core.typesr   r   ro   r   r   r   r1   r   xarray.core.datasetr   r   r   r   r   r   r,   r*   <module>r      s!   " " " " " " 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8     " " " " " " - - - - - - - - 2 2 2 2 2 2 2 2 4 4 4 4 4 4 4 4 3 3 3 3 3 3 , , , , , , , ,  ' #: $5) %p  ,//////++++++JG JG JG JG JGwx  JG JG JGZ4 4 4 4 4- 4 4 45 5 5 5 5hy) 5 5 5V V V4  #[ 1 1 1  /9 - - - - -r,   