a
    �ù»j$[  ã                   @   s  d Z ddlZddlm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„ Zdd„ Zdd„ Zdd„ Zd1dd„Zddœdd„Zdd„ Zdd„ Zdd„ Zdd „ Zd!d"„ Zd#d$„ Zd2d%d&„Z d3d'd(„Z!d)d*„ Z"d+d,„ Z#d-d.„ Z$d/d0„ Z%dS )4zBA collection of utilities to work with sparse matrices and arrays.é    N)ÚLinearOperatoré   )Ú_sparse_min_maxÚ_sparse_nan_min_max)Ú_check_sample_weighté   )Úcsc_mean_variance_axis0)Úcsr_mean_variance_axis0)Úincr_mean_variance_axis0c                 C   s,   t  | ¡r| jnt| ƒ}d| }t|ƒ‚dS )z2Raises a TypeError if X is not a CSR or CSC matrixz,Expected a CSR or CSC sparse matrix, got %s.N)ÚspÚissparseÚformatÚtypeÚ	TypeError)ÚXZ
input_typeÚerr© r   ú?E:\soccer\ml_env\Lib\site-packages\sklearn/utils/sparsefuncs.pyÚ_raise_typeerror   s    r   c                 C   s   | dvrt d|  ƒ‚d S )N)r   r   z8Unknown axis value: %d. Use 0 for rows, or 1 for columns)Ú
ValueError©Úaxisr   r   r   Ú_raise_error_wrong_axis   s    ÿr   c                 C   s6   |j d | j d ksJ ‚|  j|j| jdd�9  _dS )a‘  Inplace column scaling of a CSR matrix.

    Scale each feature of the data matrix by multiplying with specific scale
    provided by the caller assuming a (n_samples, n_features) shape.

    Parameters
    ----------
    X : sparse matrix of shape (n_samples, n_features)
        Matrix to normalize using the variance of the features.
        It should be of CSR format.

    scale : ndarray of shape (n_features,), dtype={np.float32, np.float64}
        Array of precomputed feature-wise values to use for scaling.

    Examples
    --------
    >>> from sklearn.utils import sparsefuncs
    >>> from scipy import sparse
    >>> import numpy as np
    >>> indptr = np.array([0, 3, 4, 4, 4])
    >>> indices = np.array([0, 1, 2, 2])
    >>> data = np.array([8, 1, 2, 5])
    >>> scale = np.array([2, 3, 2])
    >>> csr = sparse.csr_matrix((data, indices, indptr))
    >>> csr.todense()
    matrix([[8, 1, 2],
            [0, 0, 5],
            [0, 0, 0],
            [0, 0, 0]])
    >>> sparsefuncs.inplace_csr_column_scale(csr, scale)
    >>> csr.todense()
    matrix([[16,  3,  4],
            [ 0,  0, 10],
            [ 0,  0,  0],
            [ 0,  0,  0]])
    r   r   Zclip)ÚmodeN)ÚshapeÚdataZtakeÚindices©r   Úscaler   r   r   Úinplace_csr_column_scale%   s    %r   c                 C   s:   |j d | j d ksJ ‚|  jt |t | j¡¡9  _dS )aÂ  Inplace row scaling of a CSR matrix.

    Scale each sample of the data matrix by multiplying with specific scale
    provided by the caller assuming a (n_samples, n_features) shape.

    Parameters
    ----------
    X : sparse matrix of shape (n_samples, n_features)
        Matrix to be scaled. It should be of CSR format.

    scale : ndarray of float of shape (n_samples,)
        Array of precomputed sample-wise values to use for scaling.
    r   N)r   r   ÚnpÚrepeatÚdiffÚindptrr   r   r   r   Úinplace_csr_row_scaleN   s    r$   Fc                 C   sŒ   t |ƒ t | ¡rD| jdkrD|dkr2t| ||d�S t| j||d�S nDt | ¡r€| jdkr€|dkrnt| ||d�S t| j||d�S nt| ƒ dS )a{  Compute mean and variance along an axis on a CSR or CSC matrix.

    Parameters
    ----------
    X : sparse matrix of shape (n_samples, n_features)
        Input data. It can be of CSR or CSC format.

    axis : {0, 1}
        Axis along which the axis should be computed.

    weights : ndarray of shape (n_samples,) or (n_features,), default=None
        If axis is set to 0 shape is (n_samples,) or
        if axis is set to 1 shape is (n_features,).
        If it is set to None, then samples are equally weighted.

        .. versionadded:: 0.24

    return_sum_weights : bool, default=False
        If True, returns the sum of weights seen for each feature
        if `axis=0` or each sample if `axis=1`.

        .. versionadded:: 0.24

    Returns
    -------

    means : ndarray of shape (n_features,), dtype=floating
        Feature-wise means.

    variances : ndarray of shape (n_features,), dtype=floating
        Feature-wise variances.

    sum_weights : ndarray of shape (n_features,), dtype=floating
        Returned if `return_sum_weights` is `True`.

    Examples
    --------
    >>> from sklearn.utils import sparsefuncs
    >>> from scipy import sparse
    >>> import numpy as np
    >>> indptr = np.array([0, 3, 4, 4, 4])
    >>> indices = np.array([0, 1, 2, 2])
    >>> data = np.array([8, 1, 2, 5])
    >>> scale = np.array([2, 3, 2])
    >>> csr = sparse.csr_matrix((data, indices, indptr))
    >>> csr.todense()
    matrix([[8, 1, 2],
            [0, 0, 5],
            [0, 0, 0],
            [0, 0, 0]])
    >>> sparsefuncs.mean_variance_axis(csr, axis=0)
    (array([2.  , 0.25, 1.75]), array([12.    ,  0.1875,  4.1875]))
    Úcsrr   )ÚweightsÚreturn_sum_weightsÚcscN)r   r   r   r   Ú_csr_mean_var_axis0Ú_csc_mean_var_axis0ÚTr   )r   r   r&   r'   r   r   r   Úmean_variance_axis`   s$    6ÿÿÿÿr,   )r&   c                C   s*  t |ƒ t | ¡r| jdv s$t| ƒ t |¡dkrFtj|j||j	d�}t |¡t |¡  krlt |¡ksvn t
dƒ‚|dkr¶t |¡| jd krìt
d| jd › dt |¡› d�ƒ‚n6t |¡| jd krìt
d	| jd › dt |¡› d�ƒ‚|dkrú| jn| } |d
u�rt|| | j	d�}t| ||||d�S )aì  Compute incremental mean and variance along an axis on a CSR or CSC matrix.

    last_mean, last_var are the statistics computed at the last step by this
    function. Both must be initialized to 0-arrays of the proper size, i.e.
    the number of features in X. last_n is the number of samples encountered
    until now.

    Parameters
    ----------
    X : CSR or CSC sparse matrix of shape (n_samples, n_features)
        Input data.

    axis : {0, 1}
        Axis along which the axis should be computed.

    last_mean : ndarray of shape (n_features,) or (n_samples,), dtype=floating
        Array of means to update with the new data X.
        Should be of shape (n_features,) if axis=0 or (n_samples,) if axis=1.

    last_var : ndarray of shape (n_features,) or (n_samples,), dtype=floating
        Array of variances to update with the new data X.
        Should be of shape (n_features,) if axis=0 or (n_samples,) if axis=1.

    last_n : float or ndarray of shape (n_features,) or (n_samples,),             dtype=floating
        Sum of the weights seen so far, excluding the current weights
        If not float, it should be of shape (n_features,) if
        axis=0 or (n_samples,) if axis=1. If float it corresponds to
        having same weights for all samples (or features).

    weights : ndarray of shape (n_samples,) or (n_features,), default=None
        If axis is set to 0 shape is (n_samples,) or
        if axis is set to 1 shape is (n_features,).
        If it is set to None, then samples are equally weighted.

        .. versionadded:: 0.24

    Returns
    -------
    means : ndarray of shape (n_features,) or (n_samples,), dtype=floating
        Updated feature-wise means if axis = 0 or
        sample-wise means if axis = 1.

    variances : ndarray of shape (n_features,) or (n_samples,), dtype=floating
        Updated feature-wise variances if axis = 0 or
        sample-wise variances if axis = 1.

    n : ndarray of shape (n_features,) or (n_samples,), dtype=integral
        Updated number of seen samples per feature if axis=0
        or number of seen features per sample if axis=1.

        If weights is not None, n is a sum of the weights of the seen
        samples or features instead of the actual number of seen
        samples or features.

    Notes
    -----
    NaNs are ignored in the algorithm.

    Examples
    --------
    >>> from sklearn.utils import sparsefuncs
    >>> from scipy import sparse
    >>> import numpy as np
    >>> indptr = np.array([0, 3, 4, 4, 4])
    >>> indices = np.array([0, 1, 2, 2])
    >>> data = np.array([8, 1, 2, 5])
    >>> scale = np.array([2, 3, 2])
    >>> csr = sparse.csr_matrix((data, indices, indptr))
    >>> csr.todense()
    matrix([[8, 1, 2],
            [0, 0, 5],
            [0, 0, 0],
            [0, 0, 0]])
    >>> sparsefuncs.incr_mean_variance_axis(
    ...     csr, axis=0, last_mean=np.zeros(3), last_var=np.zeros(3), last_n=2
    ... )
    (array([1.3..., 0.1..., 1.1...]), array([8.8..., 0.1..., 3.4...]),
    array([6., 6., 6.]))
    )r(   r%   r   )Údtypez8last_mean, last_var, last_n do not have the same shapes.r   zHIf axis=1, then last_mean, last_n, last_var should be of size n_samples z (Got z).zIIf axis=0, then last_mean, last_n, last_var should be of size n_features N)Ú	last_meanÚlast_varÚlast_nr&   )r   r   r   r   r   r    ÚsizeÚfullr   r-   r   r+   r   Ú_incr_mean_var_axis0)r   r   r.   r/   r0   r&   r   r   r   Úincr_mean_variance_axis®   s<    Q(ÿÿÿÿÿÿ

ÿr4   c                 C   sN   t  | ¡r"| jdkr"t| j|ƒ n(t  | ¡rB| jdkrBt| |ƒ nt| ƒ dS )a˜  Inplace column scaling of a CSC/CSR matrix.

    Scale each feature of the data matrix by multiplying with specific scale
    provided by the caller assuming a (n_samples, n_features) shape.

    Parameters
    ----------
    X : sparse matrix of shape (n_samples, n_features)
        Matrix to normalize using the variance of the features. It should be
        of CSC or CSR format.

    scale : ndarray of shape (n_features,), dtype={np.float32, np.float64}
        Array of precomputed feature-wise values to use for scaling.

    Examples
    --------
    >>> from sklearn.utils import sparsefuncs
    >>> from scipy import sparse
    >>> import numpy as np
    >>> indptr = np.array([0, 3, 4, 4, 4])
    >>> indices = np.array([0, 1, 2, 2])
    >>> data = np.array([8, 1, 2, 5])
    >>> scale = np.array([2, 3, 2])
    >>> csr = sparse.csr_matrix((data, indices, indptr))
    >>> csr.todense()
    matrix([[8, 1, 2],
            [0, 0, 5],
            [0, 0, 0],
            [0, 0, 0]])
    >>> sparsefuncs.inplace_column_scale(csr, scale)
    >>> csr.todense()
    matrix([[16,  3,  4],
            [ 0,  0, 10],
            [ 0,  0,  0],
            [ 0,  0,  0]])
    r(   r%   N)r   r   r   r$   r+   r   r   r   r   r   r   Úinplace_column_scale!  s
    %r5   c                 C   sN   t  | ¡r"| jdkr"t| j|ƒ n(t  | ¡rB| jdkrBt| |ƒ nt| ƒ dS )aŽ  Inplace row scaling of a CSR or CSC matrix.

    Scale each row of the data matrix by multiplying with specific scale
    provided by the caller assuming a (n_samples, n_features) shape.

    Parameters
    ----------
    X : sparse matrix of shape (n_samples, n_features)
        Matrix to be scaled. It should be of CSR or CSC format.

    scale : ndarray of shape (n_features,), dtype={np.float32, np.float64}
        Array of precomputed sample-wise values to use for scaling.

    Examples
    --------
    >>> from sklearn.utils import sparsefuncs
    >>> from scipy import sparse
    >>> import numpy as np
    >>> indptr = np.array([0, 2, 3, 4, 5])
    >>> indices = np.array([0, 1, 2, 3, 3])
    >>> data = np.array([8, 1, 2, 5, 6])
    >>> scale = np.array([2, 3, 4, 5])
    >>> csr = sparse.csr_matrix((data, indices, indptr))
    >>> csr.todense()
    matrix([[8, 1, 0, 0],
            [0, 0, 2, 0],
            [0, 0, 0, 5],
            [0, 0, 0, 6]])
    >>> sparsefuncs.inplace_row_scale(csr, scale)
    >>> csr.todense()
     matrix([[16,  2,  0,  0],
             [ 0,  0,  6,  0],
             [ 0,  0,  0, 20],
             [ 0,  0,  0, 30]])
    r(   r%   N)r   r   r   r   r+   r$   r   r   r   r   r   Úinplace_row_scaleN  s
    $r6   c                 C   sv   ||fD ]}t |tjƒrtdƒ‚q|dk r8|| jd 7 }|dk rN|| jd 7 }| j|k}|| j| j|k< || j|< dS )aK  Swap two rows of a CSC matrix in-place.

    Parameters
    ----------
    X : sparse matrix of shape (n_samples, n_features)
        Matrix whose two rows are to be swapped. It should be of
        CSC format.

    m : int
        Index of the row of X to be swapped.

    n : int
        Index of the row of X to be swapped.
    ú m and n should be valid integersr   N)Ú
isinstancer    Úndarrayr   r   r   )r   ÚmÚnÚtZm_maskr   r   r   Úinplace_swap_row_cscz  s    

r=   c              	   C   sx  ||fD ]}t |tjƒrtdƒ‚q|dk r8|| jd 7 }|dk rN|| jd 7 }||kr`|| }}| j}|| }||d  }|| }||d  }|| }	|| }
|	|
krä| j|d |…  |
|	 7  < ||
 | j|d < ||	 | j|< t | jd|… | j||… | j||… | j||… | j|d… g¡| _t | jd|… | j||… | j||… | j||… | j|d… g¡| _dS )aK  Swap two rows of a CSR matrix in-place.

    Parameters
    ----------
    X : sparse matrix of shape (n_samples, n_features)
        Matrix whose two rows are to be swapped. It should be of
        CSR format.

    m : int
        Index of the row of X to be swapped.

    n : int
        Index of the row of X to be swapped.
    r7   r   r   r   N)	r8   r    r9   r   r   r#   Zconcatenater   r   )r   r:   r;   r<   r#   Zm_startZm_stopZn_startZn_stopZnz_mZnz_nr   r   r   Úinplace_swap_row_csr—  sH    

ûÿ	ûÿr>   c                 C   sP   t  | ¡r"| jdkr"t| ||ƒ n*t  | ¡rD| jdkrDt| ||ƒ nt| ƒ dS )a£  
    Swap two rows of a CSC/CSR matrix in-place.

    Parameters
    ----------
    X : sparse matrix of shape (n_samples, n_features)
        Matrix whose two rows are to be swapped. It should be of CSR or
        CSC format.

    m : int
        Index of the row of X to be swapped.

    n : int
        Index of the row of X to be swapped.

    Examples
    --------
    >>> from sklearn.utils import sparsefuncs
    >>> from scipy import sparse
    >>> import numpy as np
    >>> indptr = np.array([0, 2, 3, 3, 3])
    >>> indices = np.array([0, 2, 2])
    >>> data = np.array([8, 2, 5])
    >>> csr = sparse.csr_matrix((data, indices, indptr))
    >>> csr.todense()
    matrix([[8, 0, 2],
            [0, 0, 5],
            [0, 0, 0],
            [0, 0, 0]])
    >>> sparsefuncs.inplace_swap_row(csr, 0, 1)
    >>> csr.todense()
    matrix([[0, 0, 5],
            [8, 0, 2],
            [0, 0, 0],
            [0, 0, 0]])
    r(   r%   N)r   r   r   r=   r>   r   ©r   r:   r;   r   r   r   Úinplace_swap_rowÖ  s
    %r@   c                 C   s|   |dk r|| j d 7 }|dk r,|| j d 7 }t | ¡rN| jdkrNt| ||ƒ n*t | ¡rp| jdkrpt| ||ƒ nt| ƒ dS )a²  
    Swap two columns of a CSC/CSR matrix in-place.

    Parameters
    ----------
    X : sparse matrix of shape (n_samples, n_features)
        Matrix whose two columns are to be swapped. It should be of
        CSR or CSC format.

    m : int
        Index of the column of X to be swapped.

    n : int
        Index of the column of X to be swapped.

    Examples
    --------
    >>> from sklearn.utils import sparsefuncs
    >>> from scipy import sparse
    >>> import numpy as np
    >>> indptr = np.array([0, 2, 3, 3, 3])
    >>> indices = np.array([0, 2, 2])
    >>> data = np.array([8, 2, 5])
    >>> csr = sparse.csr_matrix((data, indices, indptr))
    >>> csr.todense()
    matrix([[8, 0, 2],
            [0, 0, 5],
            [0, 0, 0],
            [0, 0, 0]])
    >>> sparsefuncs.inplace_swap_column(csr, 0, 1)
    >>> csr.todense()
    matrix([[0, 8, 2],
            [0, 0, 5],
            [0, 0, 0],
            [0, 0, 0]])
    r   r   r(   r%   N)r   r   r   r   r>   r=   r   r?   r   r   r   Úinplace_swap_column  s    %rA   c                 C   s>   t  | ¡r2| jdv r2|r$t| |d�S t| |d�S nt| ƒ dS )a�  Compute minimum and maximum along an axis on a CSR or CSC matrix.

     Optionally ignore NaN values.

    Parameters
    ----------
    X : sparse matrix of shape (n_samples, n_features)
        Input data. It should be of CSR or CSC format.

    axis : {0, 1}
        Axis along which the axis should be computed.

    ignore_nan : bool, default=False
        Ignore or passing through NaN values.

        .. versionadded:: 0.20

    Returns
    -------

    mins : ndarray of shape (n_features,), dtype={np.float32, np.float64}
        Feature-wise minima.

    maxs : ndarray of shape (n_features,), dtype={np.float32, np.float64}
        Feature-wise maxima.
    )r%   r(   r   N)r   r   r   r   r   r   )r   r   Z
ignore_nanr   r   r   Úmin_max_axis4  s
    rB   c                 C   sö   |dkrd}n(|dkrd}n| j dkr6td  | j ¡ƒ‚|du rb|du rL| jS t t | j¡|¡S n�|dkr�t | j¡}|du rˆ| d¡S || S |dkrä|du r¶tj| j	| j
d d	�S t |t | j¡¡}tj| j	| j
d |d
�S ntd  |¡ƒ‚dS )a¾  A variant of X.getnnz() with extension to weighting on axis 0.

    Useful in efficiently calculating multilabel metrics.

    Parameters
    ----------
    X : sparse matrix of shape (n_samples, n_labels)
        Input data. It should be of CSR format.

    axis : {0, 1}, default=None
        The axis on which the data is aggregated.

    sample_weight : array-like of shape (n_samples,), default=None
        Weight for each row of X.

    Returns
    -------
    nnz : int, float, ndarray of shape (n_samples,) or ndarray of shape (n_features,)
        Number of non-zero values in the array along a given axis. Otherwise,
        the total number of non-zero values in the array is returned.
    éÿÿÿÿr   éþÿÿÿr   r%   z#Expected CSR sparse format, got {0}NZintp)Ú	minlength)rE   r&   zUnsupported axis: {0})r   r   Znnzr    Údotr"   r#   ZastypeZbincountr   r   r!   r   )r   r   Zsample_weightÚoutr&   r   r   r   Úcount_nonzeroX  s*    

rH   c                 C   sp   t | ƒ| }|stjS t | dk ¡}t|dƒ\}}|  ¡  |rLt|| ||ƒS t|d | ||ƒt|| ||ƒ d S )z”Compute the median of data with n_zeros additional zeros.

    This function is used to support sparse matrices; it modifies data
    in-place.
    r   r   r   g       @)Úlenr    ÚnanrH   ÚdivmodÚsortÚ_get_elem_at_rank)r   Ún_zerosZn_elemsÚ
n_negativeÚmiddleZis_oddr   r   r   Ú_get_medianŽ  s    ÿýrQ   c                 C   s,   | |k r||  S | | |k r dS || |  S )z@Find the value in data augmented with n_zeros for the given rankr   r   )Zrankr   rO   rN   r   r   r   rM   ¤  s
    rM   c           
      C   s˜   t  | ¡r| jdks"td| j ƒ‚| j}| j\}}t |¡}tt	|dd… |dd… ƒƒD ]8\}\}}t 
| j||… ¡}||j }	t||	ƒ||< qZ|S )aC  Find the median across axis 0 of a CSC matrix.

    It is equivalent to doing np.median(X, axis=0).

    Parameters
    ----------
    X : sparse matrix of shape (n_samples, n_features)
        Input data. It should be of CSC format.

    Returns
    -------
    median : ndarray of shape (n_features,)
        Median.
    r(   z%Expected matrix of CSC format, got %sNrC   r   )r   r   r   r   r#   r   r    ZzerosÚ	enumerateÚzipÚcopyr   r1   rQ   )
r   r#   Z	n_samplesZ
n_featuresZmedianZf_indÚstartÚendr   Znzr   r   r   Úcsc_median_axis_0­  s    

*
rW   c                    sV   ˆddd…f ‰ˆ j ‰t‡ ‡fdd„‡ ‡fdd„‡‡fdd„‡‡fdd„ˆ jˆ jd�S )aA  Create an implicitly offset linear operator.

    This is used by PCA on sparse data to avoid densifying the whole data
    matrix.

    Params
    ------
        X : sparse matrix of shape (n_samples, n_features)
        offset : ndarray of shape (n_features,)

    Returns
    -------
    centered : LinearOperator
    Nc                    s   ˆ |  ˆ|   S ©Nr   ©Úx©r   Úoffsetr   r   Ú<lambda>Þ  ó    z)_implicit_column_offset.<locals>.<lambda>c                    s   ˆ |  ˆ|   S rX   r   rY   r[   r   r   r]   ß  r^   c                    s   ˆ |  ˆ|   ¡   S rX   )ÚsumrY   ©ÚXTr\   r   r   r]   à  r^   c                    s&   ˆ |  ˆj | jdd�d d d …f   S )Nr   r   )r+   r_   rY   r`   r   r   r]   á  r^   )ZmatvecZmatmatZrmatvecZrmatmatr-   r   )r+   r   r-   r   r[   r   )r   ra   r\   r   Ú_implicit_column_offsetÌ  s    úrb   )NF)F)NN)&Ú__doc__Únumpyr    Zscipy.sparseÚsparser   Zscipy.sparse.linalgr   Zutils.fixesr   r   Zutils.validationr   Zsparsefuncs_fastr   r*   r	   r)   r
   r3   r   r   r   r$   r,   r4   r5   r6   r=   r>   r@   rA   rB   rH   rQ   rM   rW   rb   r   r   r   r   Ú<module>   s4   )
Ns-,?-1
$
6	