U
    /e{)                     @   s   d dl Z d dlmZ d dlmZ d dlmZ d dlZd dl	m
Z
 d dlmZ d dlmZ d dlmZ d d	lmZ d d
lmZ eejdddZdd Zdd ZdddZdddZdS )    N)Iterator)wraps)Number)merge)Array)
_numpy_122)
percentile)tokenize)HighLevelGraphlinearc                 C   s"  t | }t | sd |fS t|tr*t|}| jjdkrlt| jj||d}dd l	}|j
|| jj| jj|fS t| jjdkrdd l	}t| |j|jfr| j} t| jtjr| }|d}t|||d|j}|d dkrt|d | |d< ||fS t| jtjsd}t| ||d|fS )Ncategory)methodr   ZDatetimeTZDtypei8nearest)len
isinstancer   listdtypenamenp_percentilecatcodespandasCategorical
from_codes
categoriesorderedtype__name__ZSeriesZIndexvaluesnp
issubdtypeZ
datetime64viewZastypeminnumber)aqr   nresultpdr   Za2 r*   9/tmp/pip-unpacked-wheel-dbjnr7gq/dask/array/percentile.py_percentile   s.    

r,   c                 C   s    ddl m} | }||  |S )Nr   TDigest)crickr.   update)r%   r.   tr*   r*   r+   _tdigest_chunk/   s    
r2   c                 C   s0   ddl m} | }|j|  t|| d S )Nr   r-   g      Y@)r/   r.   r   r    arrayZquantile)qsdigestsr.   r1   r*   r*   r+   _percentiles_from_tdigest9   s    
r6   defaultc                    s6  ddl m  ddlm}m} dddg}|kr>tdt }d|kr`trVtd	t |	d|rvt
d
|  | jdkstdt|tr|g}|||| d}t| |}| j}	t|	tjr|g |	|| dd j}	|| |	d}
||krtd| |dkrdkrt|	tjs8t|	tjrddlm} |dd d| fddt|  D }d| }|dft|t|fi}nrtj|ddddd< d|  fddt|  D }d | }|dft|gt| j d  t|fi}t!||}t"j#||| gd!}t$||t|ff|
d"S )#u  Approximate percentile of 1-D array

    Parameters
    ----------
    a : Array
    q : array_like of float
        Percentile or sequence of percentiles to compute, which must be between
        0 and 100 inclusive.
    method : {'linear', 'lower', 'higher', 'midpoint', 'nearest'}, optional
        The interpolation method to use when the desired percentile lies
        between two data points ``i < j``. Only valid for ``method='dask'``.

        - 'linear': ``i + (j - i) * fraction``, where ``fraction``
          is the fractional part of the index surrounded by ``i``
          and ``j``.
        - 'lower': ``i``.
        - 'higher': ``j``.
        - 'nearest': ``i`` or ``j``, whichever is nearest.
        - 'midpoint': ``(i + j) / 2``.

        .. versionchanged:: 2022.1.0
            This argument was previously called "interpolation"

    internal_method : {'default', 'dask', 'tdigest'}, optional
        What internal method to use. By default will use dask's internal custom
        algorithm (``'dask'``).  If set to ``'tdigest'`` will use tdigest for
        floats and ints and fallback to the ``'dask'`` otherwise.

        .. versionchanged:: 2022.1.0
            This argument was previously called “method”.

    interpolation : str, optional
        Deprecated name for the method keyword argument.

        .. deprecated:: 2022.1.0

    See Also
    --------
    numpy.percentile : Numpy's equivalent Percentile function
    r   )percentile_lookup)
array_safemeta_from_arrayr7   ZdaskZtdigestzJIn Dask 2022.1.0, the `method=` argument was renamed to `internal_method=`interpolationzXIn Dask 2022.1.0, the `interpolation=` argument to percentile was renamed to `method= ` z0percentile() got an unexpected keyword argument    z+Percentiles only implemented for 1-d arrayslike)r   r>         ?)r   z"`internal_method=` must be one of r   )import_requiredr/   z=crick is a required dependency for using the t-digest method.zpercentile_tdigest_chunk-c                    s   i | ]\}} |ft |fqS r*   )r2   .0ikey)r   r*   r+   
<dictcomp>   s     zpercentile.<locals>.<dictcomp>zpercentile_tdigest-Zconstant)moded   zpercentile_chunk-c                    s"   i | ]\}}|f |fqS r*   r*   rA   r,   Zcalc_qr   r   r*   r+   rE      s    zpercentile-)Zdependencies)chunksmeta)%Zdask.array.dispatchr8   dask.array.utilsr9   r:   warningswarnFutureWarningr   pop	TypeErrorkeysndimNotImplementedErrorr   r   r	   r   r    r!   integer
ValueErrorZfloatingZ
dask.utilsr@   	enumerateZ__dask_keys__r6   sortedpadmerge_percentilesr   rJ   r   r
   Zfrom_collectionsr   )r%   r&   r   Zinternal_methodkwargsr9   r:   Zallowed_internal_methodstokenr   rK   r@   ZdskZname2Zdsk2graphr*   rI   r+   r   C   s    )




 




r   lowerTc                 C   s  ddl m} t| trt| } || | d} ttt|}t|}|dkrTt| \}}t|}ttdd t|||D  }|s|rtdt	t
|d d tjS |\}}}|d jjd	krt| |d
d |D |||}ddl}	|	j||d j|d jS t|d jtjsd}t
|t
|ks<t
|t
|krDtdg }
t||D ]X\}}tj| t
|d}t|||d d|dd< |d |d< ||9 }|
| qRt|}|t|
|d}t|}t||}t||}t|}|| |d} | t| }|dkr&t|||}ntj||dd}tj||ddd }t |t
|d | t ||}t!||}|dkr|| }n|dkr|| }nx|dkrd|| ||   }nX|dkrt"|| | }t"|| | }||k}|}|| ||< || }ntd|S )a  Combine several percentile calculations of different data.

    Parameters
    ----------

    finalq : numpy.array
        Percentiles to compute (must use same scale as ``qs``).
    qs : sequence of :class:`numpy.array`s
        Percentiles calculated on different sets of data.
    vals : sequence of :class:`numpy.array`s
        Resulting values associated with percentiles ``qs``.
    Ns : sequence of integers
        The number of data elements associated with each data set.
    method : {'linear', 'lower', 'higher', 'midpoint', 'nearest'}
        Specify the interpolation method to use to calculate final
        percentiles.  For more information, see :func:`numpy.percentile`.

    Examples
    --------

    >>> finalq = [10, 20, 30, 40, 50, 60, 70, 80]
    >>> qs = [[20, 40, 60, 80], [20, 40, 60, 80]]
    >>> vals = [np.array([1, 2, 3, 4]), np.array([10, 11, 12, 13])]
    >>> Ns = [100, 100]  # Both original arrays had 100 elements

    >>> merge_percentiles(finalq, qs, vals, Ns=Ns)
    array([ 1,  2,  3,  4, 10, 11, 12, 13])
    r   )r9   r=   Nc                 S   s    g | ]\}}}|r|||fqS r*   r*   )rB   r&   valNr*   r*   r+   
<listcomp>   s      z%merge_percentiles.<locals>.<listcomp>zNo non-trivial arrays found   r   c                 S   s   g | ]
}|j qS r*   )r   )rB   vr*   r*   r+   ra      s     r   z3qs, vals, and Ns parameters must be the same length)shaper<   r   left)Zsiderightr^   ZhigherZmidpointr?   zVinterpolation method can only be 'linear', 'lower', 'higher', 'midpoint', or 'nearest')#rL   r9   r   r   r   mapziprV   r    fullr   nanr   r   rZ   r   r   r   r   r   r!   r$   Z
empty_likeZdiffappendZconcatenateZargsortZtakeZcumsumsumZinterpZsearchsortedZminimummaximumabs)Zfinalqr4   valsr   ZNsZraise_on_nanr9   Lr(   r)   countsr&   r`   countZcombined_valsZcombined_countsZ
sort_orderZ
combined_qZ	desired_qrvre   rf   r^   upperZlower_residualZupper_residualmaskindexr*   r*   r+   rZ      s    

     $










rZ   )r   )r   r7   )r^   NT)rM   collections.abcr   	functoolsr   Znumbersr   Znumpyr    Ztlzr   Zdask.array.corer   Zdask.array.numpy_compatr   r   r   Z	dask.baser	   Zdask.highlevelgraphr
   r,   r2   r6   rZ   r*   r*   r*   r+   <module>   s"   


 