U
    !`                     @   s2  d 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m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lmZ ddlmZ ddddgZG dd deZ dd Z!dddddZ"dd Z#d&dd Z$d'd!d"Z%G d#d deeZ&ddd$d%dZ'dS )(z
The :mod:`sklearn.pipeline` module implements utilities to build a composite
estimator, as a chain of transforms and estimators.
    )defaultdict)isliceN)sparse)Parallel   )cloneTransformerMixin)_VisualBlock)if_delegate_has_method)Bunch_print_elapsed_time)
deprecated)
_safe_tags)check_memory)_deprecate_positional_args)delayed)_BaseCompositionPipelineFeatureUnionmake_pipeline
make_unionc                   @   s  e Zd ZdZdgZedddddZdHd	d
Zdd Zdd Z	dIddZ
dd Zdd Zedd Zedd Zedd Zdd Zdd ZdJdd ZdKd!d"ZdLd#d$Zed%d&d'd( Zed%d&dMd)d*Zed%d&d+d, Zed%d&d-d. Zed%d&d/d0 Zed%d&d1d2 Zed3d4 Zd5d6 Zed7d8 Zd9d: Z ed%d&dNd;d<Z!ed=d> Z"d?d@ Z#e$dAedBdC Z%edDdE Z&dFdG Z'dS )Or   a+  
    Pipeline of transforms with a final estimator.

    Sequentially apply a list of transforms and a final estimator.
    Intermediate steps of the pipeline must be 'transforms', that is, they
    must implement fit and transform methods.
    The final estimator only needs to implement fit.
    The transformers in the pipeline can be cached using ``memory`` argument.

    The purpose of the pipeline is to assemble several steps that can be
    cross-validated together while setting different parameters.
    For this, it enables setting parameters of the various steps using their
    names and the parameter name separated by a '__', as in the example below.
    A step's estimator may be replaced entirely by setting the parameter
    with its name to another estimator, or a transformer removed by setting
    it to 'passthrough' or ``None``.

    Read more in the :ref:`User Guide <pipeline>`.

    .. versionadded:: 0.5

    Parameters
    ----------
    steps : list
        List of (name, transform) tuples (implementing fit/transform) that are
        chained, in the order in which they are chained, with the last object
        an estimator.

    memory : str or object with the joblib.Memory interface, default=None
        Used to cache the fitted transformers of the pipeline. By default,
        no caching is performed. If a string is given, it is the path to
        the caching directory. Enabling caching triggers a clone of
        the transformers before fitting. Therefore, the transformer
        instance given to the pipeline cannot be inspected
        directly. Use the attribute ``named_steps`` or ``steps`` to
        inspect estimators within the pipeline. Caching the
        transformers is advantageous when fitting is time consuming.

    verbose : bool, default=False
        If True, the time elapsed while fitting each step will be printed as it
        is completed.

    Attributes
    ----------
    named_steps : :class:`~sklearn.utils.Bunch`
        Dictionary-like object, with the following attributes.
        Read-only attribute to access any step parameter by user given name.
        Keys are step names and values are steps parameters.

    See Also
    --------
    make_pipeline : Convenience function for simplified pipeline construction.

    Examples
    --------
    >>> from sklearn.svm import SVC
    >>> from sklearn.preprocessing import StandardScaler
    >>> from sklearn.datasets import make_classification
    >>> from sklearn.model_selection import train_test_split
    >>> from sklearn.pipeline import Pipeline
    >>> X, y = make_classification(random_state=0)
    >>> X_train, X_test, y_train, y_test = train_test_split(X, y,
    ...                                                     random_state=0)
    >>> pipe = Pipeline([('scaler', StandardScaler()), ('svc', SVC())])
    >>> # The pipeline can be used as any other estimator
    >>> # and avoids leaking the test set into the train set
    >>> pipe.fit(X_train, y_train)
    Pipeline(steps=[('scaler', StandardScaler()), ('svc', SVC())])
    >>> pipe.score(X_test, y_test)
    0.88
    stepsNFmemoryverbosec                C   s   || _ || _|| _|   d S N)r   r   r   _validate_steps)selfr   r   r    r   /lib/python3.8/site-packages/sklearn/pipeline.py__init__q   s    zPipeline.__init__Tc                 C   s   | j d|dS )a  Get parameters for this estimator.

        Returns the parameters given in the constructor as well as the
        estimators contained within the `steps` of the `Pipeline`.

        Parameters
        ----------
        deep : bool, default=True
            If True, will return the parameters for this estimator and
            contained subobjects that are estimators.

        Returns
        -------
        params : mapping of string to any
            Parameter names mapped to their values.
        r   deepZ_get_paramsr   r"   r   r   r   
get_paramsx   s    zPipeline.get_paramsc                 K   s   | j d| | S )a  Set the parameters of this estimator.

        Valid parameter keys can be listed with ``get_params()``. Note that
        you can directly set the parameters of the estimators contained in
        `steps`.

        Returns
        -------
        self
        r   )r   Z_set_paramsr   kwargsr   r   r   
set_params   s    zPipeline.set_paramsc                 C   s   t | j \}}| | |d d }|d }|D ]H}|d ks0|dkrFq0t|dsZt|drdt|ds0td|t|f q0|d k	r|dkrt|dstd|t|f d S )Npassthroughfitfit_transform	transformzAll intermediate steps should be transformers and implement fit and transform or be the string 'passthrough' '%s' (type %s) doesn'tzaLast step of Pipeline should implement fit or be the string 'passthrough'. '%s' (type %s) doesn't)zipr   _validate_nameshasattr	TypeErrortype)r   names
estimatorstransformers	estimatortr   r   r   r      s*    


zPipeline._validate_stepsc                 c   sh   t | j}|s|d8 }tt| jd|D ]:\}\}}|sF|||fV  q(|dk	r(|dkr(|||fV  q(dS )z
        Generate (idx, (name, trans)) tuples from self.steps

        When filter_passthrough is True, 'passthrough' and None transformers
        are filtered out.
        r   r   Nr+   )lenr   	enumerater   )r   
with_finalfilter_passthroughstopidxnametransr   r   r   _iter   s    
zPipeline._iterc                 C   s
   t | jS )z4
        Returns the length of the Pipeline
        )r9   r   r   r   r   r   __len__   s    zPipeline.__len__c                 C   sl   t |tr6|jdkrtd| j| j| | j| jdS z| j| \}}W n tk
rf   | j	|  Y S X |S )a  Returns a sub-pipeline or a single esimtator in the pipeline

        Indexing with an integer will return an estimator; using a slice
        returns another Pipeline instance which copies a slice of this
        Pipeline. This copy is shallow: modifying (or fitting) estimators in
        the sub-pipeline will affect the larger pipeline and vice-versa.
        However, replacing a value in `step` will not affect a copy.
        )r   Nz*Pipeline slicing only supports a step of 1r   )

isinstanceslicestep
ValueError	__class__r   r   r   r2   named_steps)r   Zindr?   estr   r   r   __getitem__   s    	

  zPipeline.__getitem__c                 C   s   | j d d jS )Nr*   r   )r   _estimator_typerB   r   r   r   rL      s    zPipeline._estimator_typec                 C   s   t f t| jS r   )r   dictr   rB   r   r   r   rI      s    zPipeline.named_stepsc                 C   s   | j d d }|d krdS |S )Nr*   r   r+   )r   )r   r7   r   r   r   _final_estimator   s    zPipeline._final_estimatorc                 C   s0   | j s
d S | j| \}}d|d t| j|f S )N(step %d of %d) Processing %sr   )r   r   r9   )r   step_idxr?   rF   r   r   r   _log_message   s    zPipeline._log_messagec                 K   sX   dd | j D }| D ]:\}}d|kr6td||dd\}}||| |< q|S )Nc                 S   s   i | ]\}}|d k	r|i qS r   r   ).0r?   rF   r   r   r   
<dictcomp>   s     z.Pipeline._check_fit_params.<locals>.<dictcomp>__zPipeline.fit does not accept the {} parameter. You can pass parameters to specific steps of your pipeline using the stepname__parameter format, e.g. `Pipeline.fit(X, y, logisticregression__sample_weight=sample_weight)`.r   )r   itemsrG   formatsplit)r   
fit_paramsfit_params_stepsZpnameZpvalrF   Zparamr   r   r   _check_fit_params   s    zPipeline._check_fit_paramsc              
   K   s  t | j| _|   t| j}|t}| jdddD ]\}}}|d ksP|dkrxtd| 	| W 5 Q R  q6W 5 Q R X t
|dr|jd kr|}	qt|}	n,t
|dr|jd kr|}	qt|}	nt|}	||	||d fd| 	|d|| \}}
||
f| j|< q6|S )NF)r;   r<   r+   r   locationcachedirmessage_clsnamemessage)listr   r   r   r   cache_fit_transform_onerA   r   rQ   r1   r[   r   r\   )r   XyrY   r   Zfit_transform_one_cachedrP   r?   transformerZcloned_transformerZfitted_transformerr   r   r   _fit
  sJ    







   
zPipeline._fitc              	   K   st   | j f |}| j||f|}td| t| jd 4 | jdkrf|| jd d  }| jj||f| W 5 Q R X | S )a  Fit the model

        Fit all the transforms one after the other and transform the
        data, then fit the transformed data using the final estimator.

        Parameters
        ----------
        X : iterable
            Training data. Must fulfill input requirements of first step of the
            pipeline.

        y : iterable, default=None
            Training targets. Must fulfill label requirements for all steps of
            the pipeline.

        **fit_params : dict of string -> object
            Parameters passed to the ``fit`` method of each step, where
            each parameter name is prefixed such that parameter ``p`` for step
            ``s`` has key ``s__p``.

        Returns
        -------
        self : Pipeline
            This estimator
        r   r   r+   r*   r   )rZ   rf   r   rQ   r9   r   rN   r,   )r   rc   rd   rX   rY   Xtfit_params_last_stepr   r   r   r,   :  s    
zPipeline.fitc              
   K   s   | j f |}| j||f|}| j}td| t| jd x |dkrV|W  5 Q R  S || jd d  }t|dr|j||f|W  5 Q R  S |j	||f|
|W  5 Q R  S W 5 Q R X dS )a  Fit the model and transform with the final estimator

        Fits all the transforms one after the other and transforms the
        data, then uses fit_transform on transformed data with the final
        estimator.

        Parameters
        ----------
        X : iterable
            Training data. Must fulfill input requirements of first step of the
            pipeline.

        y : iterable, default=None
            Training targets. Must fulfill label requirements for all steps of
            the pipeline.

        **fit_params : dict of string -> object
            Parameters passed to the ``fit`` method of each step, where
            each parameter name is prefixed such that parameter ``p`` for step
            ``s`` has key ``s__p``.

        Returns
        -------
        Xt : array-like of shape  (n_samples, n_transformed_features)
            Transformed samples
        r   r   r+   r*   r   r-   N)rZ   rf   rN   r   rQ   r9   r   r1   r-   r,   r.   )r   rc   rd   rX   rY   rg   Z	last_steprh   r   r   r   r-   ^  s     

zPipeline.fit_transformrN   )Zdelegatec                 K   s>   |}| j ddD ]\}}}||}q| jd d j|f|S )a  Apply transforms to the data, and predict with the final estimator

        Parameters
        ----------
        X : iterable
            Data to predict on. Must fulfill input requirements of first step
            of the pipeline.

        **predict_params : dict of string -> object
            Parameters to the ``predict`` called at the end of all
            transformations in the pipeline. Note that while this may be
            used to return uncertainties from some models with return_std
            or return_cov, uncertainties that are generated by the
            transformations in the pipeline are not propagated to the
            final estimator.

            .. versionadded:: 0.20

        Returns
        -------
        y_pred : array-like
        Fr;   r*   )rA   r.   r   predict)r   rc   Zpredict_paramsrg   _r?   r.   r   r   r   rj     s    zPipeline.predictc              	   K   sr   | j f |}| j||f|}|| jd d  }td| t| jd   | jd d j||f|}W 5 Q R X |S )ao  Applies fit_predict of last step in pipeline after transforms.

        Applies fit_transforms of a pipeline to the data, followed by the
        fit_predict method of the final estimator in the pipeline. Valid
        only if the final estimator implements fit_predict.

        Parameters
        ----------
        X : iterable
            Training data. Must fulfill input requirements of first step of
            the pipeline.

        y : iterable, default=None
            Training targets. Must fulfill label requirements for all steps
            of the pipeline.

        **fit_params : dict of string -> object
            Parameters passed to the ``fit`` method of each step, where
            each parameter name is prefixed such that parameter ``p`` for step
            ``s`` has key ``s__p``.

        Returns
        -------
        y_pred : array-like
        r*   r   r   r   )rZ   rf   r   r   rQ   r9   fit_predict)r   rc   rd   rX   rY   rg   rh   Zy_predr   r   r   rl     s    zPipeline.fit_predictc                 C   s:   |}| j ddD ]\}}}||}q| jd d |S )aH  Apply transforms, and predict_proba of the final estimator

        Parameters
        ----------
        X : iterable
            Data to predict on. Must fulfill input requirements of first step
            of the pipeline.

        Returns
        -------
        y_proba : array-like of shape (n_samples, n_classes)
        Fri   r*   )rA   r.   r   predict_probar   rc   rg   rk   r?   r.   r   r   r   rm     s    zPipeline.predict_probac                 C   s:   |}| j ddD ]\}}}||}q| jd d |S )aL  Apply transforms, and decision_function of the final estimator

        Parameters
        ----------
        X : iterable
            Data to predict on. Must fulfill input requirements of first step
            of the pipeline.

        Returns
        -------
        y_score : array-like of shape (n_samples, n_classes)
        Fri   r*   )rA   r.   r   decision_functionrn   r   r   r   ro     s    zPipeline.decision_functionc                 C   s:   |}| j ddD ]\}}}||}q| jd d |S )a<  Apply transforms, and score_samples of the final estimator.

        Parameters
        ----------
        X : iterable
            Data to predict on. Must fulfill input requirements of first step
            of the pipeline.

        Returns
        -------
        y_score : ndarray of shape (n_samples,)
        Fri   r*   )rA   r.   r   score_samples)r   rc   rg   rk   re   r   r   r   rp     s    zPipeline.score_samplesc                 C   s:   |}| j ddD ]\}}}||}q| jd d |S )aL  Apply transforms, and predict_log_proba of the final estimator

        Parameters
        ----------
        X : iterable
            Data to predict on. Must fulfill input requirements of first step
            of the pipeline.

        Returns
        -------
        y_score : array-like of shape (n_samples, n_classes)
        Fri   r*   )rA   r.   r   predict_log_probarn   r   r   r   rq     s    zPipeline.predict_log_probac                 C   s   | j dkr| j j | jS )a  Apply transforms, and transform with the final estimator

        This also works where final estimator is ``None``: all prior
        transformations are applied.

        Parameters
        ----------
        X : iterable
            Data to transform. Must fulfill input requirements of first step
            of the pipeline.

        Returns
        -------
        Xt : array-like of shape  (n_samples, n_transformed_features)
        r+   )rN   r.   
_transformrB   r   r   r   r.     s    
zPipeline.transformc                 C   s&   |}|   D ]\}}}||}q|S r   )rA   r.   )r   rc   rg   rk   r.   r   r   r   rr   -  s    zPipeline._transformc                 C   s    |   D ]\}}}|j q| jS )a<  Apply inverse transformations in reverse order

        All estimators in the pipeline must support ``inverse_transform``.

        Parameters
        ----------
        Xt : array-like of shape  (n_samples, n_transformed_features)
            Data samples, where ``n_samples`` is the number of samples and
            ``n_features`` is the number of features. Must fulfill
            input requirements of last step of pipeline's
            ``inverse_transform`` method.

        Returns
        -------
        Xt : array-like of shape (n_samples, n_features)
        )rA   inverse_transform_inverse_transform)r   rk   r.   r   r   r   rs   3  s    zPipeline.inverse_transformc                 C   s2   |}t t|  }|D ]\}}}||}q|S r   )reversedr`   rA   rs   )r   rc   rg   Zreverse_iterrk   r.   r   r   r   rt   K  s
    zPipeline._inverse_transformc           	      C   sT   |}| j ddD ]\}}}||}qi }|dk	r:||d< | jd d j||f|S )au  Apply transforms, and score with the final estimator

        Parameters
        ----------
        X : iterable
            Data to predict on. Must fulfill input requirements of first step
            of the pipeline.

        y : iterable, default=None
            Targets used for scoring. Must fulfill label requirements for all
            steps of the pipeline.

        sample_weight : array-like, default=None
            If not None, this argument is passed as ``sample_weight`` keyword
            argument to the ``score`` method of the final estimator.

        Returns
        -------
        score : float
        Fri   Nsample_weightr*   )rA   r.   r   score)	r   rc   rd   rv   rg   rk   r?   r.   Zscore_paramsr   r   r   rw   R  s    zPipeline.scorec                 C   s   | j d d jS )Nr*   )r   classes_rB   r   r   r   rx   p  s    zPipeline.classes_c                 C   s   dt | jd d diS )NZpairwiser   r   )r   r   rB   r   r   r   
_more_tagst  s    zPipeline._more_tagszaAttribute _pairwise was deprecated in version 0.24 and will be removed in 1.1 (renaming of 0.26).c                 C   s   t | jd d ddS )Nr   r   	_pairwiseF)getattrr   rB   r   r   r   rz   z  s    zPipeline._pairwisec                 C   s   | j d d jS Nr   r   )r   n_features_in_rB   r   r   r   r}     s    zPipeline.n_features_in_c                    sJ   t | j \}}dd   fdd| jD }dd |D }td|||ddS )	Nc                 S   s,   |d ks|dkr|  dS |  d|j j S )Nr+   z: passthroughz: )rH   __name__)r?   rJ   r   r   r   	_get_name  s    
z-Pipeline._sk_visual_block_.<locals>._get_namec                    s   g | ]\}} ||qS r   r   )rR   r?   rJ   r   r   r   
<listcomp>  s     z.Pipeline._sk_visual_block_.<locals>.<listcomp>c                 S   s   g | ]}t |qS r   )str)rR   rJ   r   r   r   r     s     serialF)r4   name_detailsZdash_wrapped)r/   r   r	   )r   rk   r5   r4   r   r   r   r   _sk_visual_block_  s    zPipeline._sk_visual_block_)T)TT)N)N)N)N)NN)(r~   
__module____qualname____doc___required_parametersr   r    r%   r)   r   rA   rC   rK   propertyrL   rI   rN   rQ   rZ   rf   r,   r-   r
   rj   rl   rm   ro   rp   rq   r.   rr   rs   rt   rw   rx   ry   r   rz   r}   r   r   r   r   r   r   %   sd   I




	
0
$
*
$







c                 C   s   dd | D }t t}t| |D ]\}}||  d7  < q t| D ]\}}|dkrF||= qFttt| D ]<}|| }||krn||  d||  7  < ||  d8  < qntt|| S )zGenerate names for estimators.c                 S   s(   g | ] }t |tr|nt|j qS r   )rD   r   r3   r~   lower)rR   r7   r   r   r   r     s   z$_name_estimators.<locals>.<listcomp>r   z-%d)r   intr/   r`   rU   ru   ranger9   )r5   r4   Z	namecountrJ   r?   kvir   r   r   _name_estimators  s    r   Fr   c                 G   s   t t|| |dS )a	  Construct a Pipeline from the given estimators.

    This is a shorthand for the Pipeline constructor; it does not require, and
    does not permit, naming the estimators. Instead, their names will be set
    to the lowercase of their types automatically.

    Parameters
    ----------
    *steps : list of estimators.

    memory : str or object with the joblib.Memory interface, default=None
        Used to cache the fitted transformers of the pipeline. By default,
        no caching is performed. If a string is given, it is the path to
        the caching directory. Enabling caching triggers a clone of
        the transformers before fitting. Therefore, the transformer
        instance given to the pipeline cannot be inspected
        directly. Use the attribute ``named_steps`` or ``steps`` to
        inspect estimators within the pipeline. Caching the
        transformers is advantageous when fitting is time consuming.

    verbose : bool, default=False
        If True, the time elapsed while fitting each step will be printed as it
        is completed.

    See Also
    --------
    Pipeline : Class for creating a pipeline of transforms with a final
        estimator.

    Examples
    --------
    >>> from sklearn.naive_bayes import GaussianNB
    >>> from sklearn.preprocessing import StandardScaler
    >>> make_pipeline(StandardScaler(), GaussianNB(priors=None))
    Pipeline(steps=[('standardscaler', StandardScaler()),
                    ('gaussiannb', GaussianNB())])

    Returns
    -------
    p : Pipeline
    r   )r   r   )r   r   r   r   r   r   r     s    *c                 K   s   |  |}|d kr|S || S r   )r.   )re   rc   rd   weightrX   resr   r   r   _transform_one  s    
r    c              	   K   sd   t ||8 t| dr(| j||f|}n| j||f||}W 5 Q R X |dkrX|| fS || | fS )z
    Fits ``transformer`` to ``X`` and ``y``. The transformed result is returned
    with the fitted transformer. If ``weight`` is not ``None``, the result will
    be multiplied by ``weight``.
    r-   N)r   r1   r-   r,   r.   )re   rc   rd   r   r^   r_   rX   r   r   r   r   rb     s    
 rb   c              
   K   s2   t || | j||f|W  5 Q R  S Q R X dS )z2
    Fits ``transformer`` to ``X`` and ``y``.
    N)r   r,   )re   rc   rd   r   r^   r_   rX   r   r   r   _fit_one  s    
r   c                   @   s   e Zd ZdZdgZeddddddZd'd	d
Zdd Zdd Z	dd Z
dd Zdd Zd(ddZd)ddZdd Zdd Zdd Zdd  Zd!d" Zed#d$ Zd%d& ZdS )*r   a  Concatenates results of multiple transformer objects.

    This estimator applies a list of transformer objects in parallel to the
    input data, then concatenates the results. This is useful to combine
    several feature extraction mechanisms into a single transformer.

    Parameters of the transformers may be set using its name and the parameter
    name separated by a '__'. A transformer may be replaced entirely by
    setting the parameter with its name to another transformer,
    or removed by setting to 'drop'.

    Read more in the :ref:`User Guide <feature_union>`.

    .. versionadded:: 0.13

    Parameters
    ----------
    transformer_list : list of (string, transformer) tuples
        List of transformer objects to be applied to the data. The first
        half of each tuple is the name of the transformer. The tranformer can
        be 'drop' for it to be ignored.

        .. versionchanged:: 0.22
           Deprecated `None` as a transformer in favor of 'drop'.

    n_jobs : int, default=None
        Number of jobs to run in parallel.
        ``None`` means 1 unless in a :obj:`joblib.parallel_backend` context.
        ``-1`` means using all processors. See :term:`Glossary <n_jobs>`
        for more details.

        .. versionchanged:: v0.20
           `n_jobs` default changed from 1 to None

    transformer_weights : dict, default=None
        Multiplicative weights for features per transformer.
        Keys are transformer names, values the weights.
        Raises ValueError if key not present in ``transformer_list``.

    verbose : bool, default=False
        If True, the time elapsed while fitting each transformer will be
        printed as it is completed.

    See Also
    --------
    make_union : Convenience function for simplified feature union
        construction.

    Examples
    --------
    >>> from sklearn.pipeline import FeatureUnion
    >>> from sklearn.decomposition import PCA, TruncatedSVD
    >>> union = FeatureUnion([("pca", PCA(n_components=1)),
    ...                       ("svd", TruncatedSVD(n_components=2))])
    >>> X = [[0., 1., 3], [2., 2., 5]]
    >>> union.fit_transform(X)
    array([[ 1.5       ,  3.0...,  0.8...],
           [-1.5       ,  5.7..., -0.4...]])
    transformer_listNF)n_jobstransformer_weightsr   c                C   s$   || _ || _|| _|| _|   d S r   )r   r   r   r   _validate_transformers)r   r   r   r   r   r   r   r   r    G  s
    zFeatureUnion.__init__Tc                 C   s   | j d|dS )a  Get parameters for this estimator.

        Returns the parameters given in the constructor as well as the
        estimators contained within the `transformer_list` of the
        `FeatureUnion`.

        Parameters
        ----------
        deep : bool, default=True
            If True, will return the parameters for this estimator and
            contained subobjects that are estimators.

        Returns
        -------
        params : mapping of string to any
            Parameter names mapped to their values.
        r   r!   r#   r$   r   r   r   r%   P  s    zFeatureUnion.get_paramsc                 K   s   | j d| | S )a  Set the parameters of this estimator.

        Valid parameter keys can be listed with ``get_params()``. Note that
        you can directly set the parameters of the estimators contained in
        `tranformer_list`.

        Returns
        -------
        self
        r   )r   r&   r'   r   r   r   r)   d  s    zFeatureUnion.set_paramsc                 C   sb   t | j \}}| | |D ]@}|dkr*qt|ds>t|drHt|dstd|t|f qd S )Ndropr,   r-   r.   zIAll estimators should implement fit and transform. '%s' (type %s) doesn't)r/   r   r0   r1   r2   r3   )r   r4   r6   r8   r   r   r   r   r  s    

z#FeatureUnion._validate_transformersc                 C   sF   | j s
d S tdd | jD }| j D ]}||kr$td| dq$d S )Nc                 s   s   | ]\}}|V  qd S r   r   )rR   r?   rk   r   r   r   	<genexpr>  s     z=FeatureUnion._validate_transformer_weights.<locals>.<genexpr>z"Attempting to weight transformer "z-", but it is not present in transformer_list.)r   setr   rG   )r   Ztransformer_namesr?   r   r   r   _validate_transformer_weights  s    

z*FeatureUnion._validate_transformer_weightsc                    s    | j pi j  fdd| jD S )zg
        Generate (name, trans, weight) tuples excluding None and
        'drop' transformers.
        c                 3   s(   | ] \}}|d kr|| |fV  qdS )r   Nr   )rR   r?   r@   Z
get_weightr   r   r     s   z%FeatureUnion._iter.<locals>.<genexpr>)r   getr   rB   r   r   r   rA     s    
zFeatureUnion._iterc                    s\   g }|   D ]J\ }}t|ds:tdt t|jf | fdd| D  q|S )zGet feature names from all transformers.

        Returns
        -------
        feature_names : list of strings
            Names of the features produced by transform.
        get_feature_namesz<Transformer %s (type %s) does not provide get_feature_names.c                    s   g | ]} d  | qS )rT   r   rR   fr?   r   r   r     s     z2FeatureUnion.get_feature_names.<locals>.<listcomp>)rA   r1   AttributeErrorr   r3   r~   extendr   )r   Zfeature_namesr@   r   r   r   r   r     s    

zFeatureUnion.get_feature_namesc                 K   s&   |  |||t}|s| S | | | S )a  Fit all transformers using X.

        Parameters
        ----------
        X : iterable or array-like, depending on transformers
            Input data, used to fit transformers.

        y : array-like of shape (n_samples, n_outputs), default=None
            Targets for supervised learning.

        Returns
        -------
        self : FeatureUnion
            This estimator
        )_parallel_funcr   _update_transformer_list)r   rc   rd   rX   r6   r   r   r   r,     s
    
zFeatureUnion.fitc                 K   sH   |  |||t}|s(t|jd dfS t| \}}| | | |S )a[  Fit all transformers, transform the data and concatenate results.

        Parameters
        ----------
        X : iterable or array-like, depending on transformers
            Input data to be transformed.

        y : array-like of shape (n_samples, n_outputs), default=None
            Targets for supervised learning.

        Returns
        -------
        X_t : array-like or sparse matrix of                 shape (n_samples, sum_n_components)
            hstack of results of transformers. sum_n_components is the
            sum of n_components (output dimension) over transformers.
        r   )r   rb   npzerosshaper/   r   _hstack)r   rc   rd   rX   ZresultsXsr6   r   r   r   r-     s    
zFeatureUnion.fit_transformc                 C   s   | j s
d S d|||f S )NrO   )r   )r   r?   r>   Ztotalr   r   r   rQ     s    zFeatureUnion._log_messagec                    sV   t j_    t  tjd fddtdD S )z Runs func in parallel on X and yr   c              
   3   sF   | ]>\}\}}}t | |fd ||tdV  qdS )r   r]   N)r   rQ   r9   )rR   r>   r?   re   r   rc   rX   funcr   r6   rd   r   r   r     s   
   z.FeatureUnion._parallel_func.<locals>.<genexpr>r   )r`   r   r   r   rA   r   r   r:   )r   rc   rd   rX   r   r   r   r   r     s    zFeatureUnion._parallel_funcc                    sD   t | jd fdd|  D }|s:t jd dfS | |S )a  Transform X separately by each transformer, concatenate results.

        Parameters
        ----------
        X : iterable or array-like, depending on transformers
            Input data to be transformed.

        Returns
        -------
        X_t : array-like or sparse matrix of                 shape (n_samples, sum_n_components)
            hstack of results of transformers. sum_n_components is the
            sum of n_components (output dimension) over transformers.
        r   c                 3   s&   | ]\}}}t t| d |V  qd S r   )r   r   )rR   r?   r@   r   rc   r   r   r      s   z)FeatureUnion.transform.<locals>.<genexpr>r   )r   r   rA   r   r   r   r   )r   rc   r   r   r   r   r.     s    zFeatureUnion.transformc                 C   s0   t dd |D r"t| }n
t|}|S )Nc                 s   s   | ]}t |V  qd S r   )r   Zissparser   r   r   r   r   
  s     z'FeatureUnion._hstack.<locals>.<genexpr>)anyr   ZhstackZtocsrr   )r   r   r   r   r   r   	  s    
zFeatureUnion._hstackc                    s*   t    fdd| jD | jd d < d S )Nc                    s(   g | ] \}}||d kr|nt  fqS )r   )next)rR   r?   oldr6   r   r   r     s   z9FeatureUnion._update_transformer_list.<locals>.<listcomp>)iterr   )r   r6   r   r   r   r     s    
z%FeatureUnion._update_transformer_listc                 C   s   | j d d jS r|   )r   r}   rB   r   r   r   r}     s    zFeatureUnion.n_features_in_c                 C   s   t | j \}}td||dS )NZparallel)r4   )r/   r   r	   )r   r4   r6   r   r   r   r     s    zFeatureUnion._sk_visual_block_)T)N)N)r~   r   r   r   r   r   r    r%   r)   r   r   rA   r   r,   r-   rQ   r   r.   r   r   r   r}   r   r   r   r   r   r   	  s.   ; 




r   r   c                 G   s   t t|| |dS )a(  
    Construct a FeatureUnion from the given transformers.

    This is a shorthand for the FeatureUnion constructor; it does not require,
    and does not permit, naming the transformers. Instead, they will be given
    names automatically based on their types. It also does not allow weighting.

    Parameters
    ----------
    *transformers : list of estimators

    n_jobs : int, default=None
        Number of jobs to run in parallel.
        ``None`` means 1 unless in a :obj:`joblib.parallel_backend` context.
        ``-1`` means using all processors. See :term:`Glossary <n_jobs>`
        for more details.

        .. versionchanged:: v0.20
           `n_jobs` default changed from 1 to None

    verbose : bool, default=False
        If True, the time elapsed while fitting each transformer will be
        printed as it is completed.

    Returns
    -------
    f : FeatureUnion

    See Also
    --------
    FeatureUnion : Class for concatenating the results of multiple transformer
        objects.

    Examples
    --------
    >>> from sklearn.decomposition import PCA, TruncatedSVD
    >>> from sklearn.pipeline import make_union
    >>> make_union(PCA(), TruncatedSVD())
     FeatureUnion(transformer_list=[('pca', PCA()),
                                   ('truncatedsvd', TruncatedSVD())])
    r   )r   r   )r   r   r6   r   r   r   r      s
    *  )r   N)r   N)(r   collectionsr   	itertoolsr   Znumpyr   Zscipyr   Zjoblibr   baser   r   Zutils._estimator_html_reprr	   Zutils.metaestimatorsr
   Zutilsr   r   Zutils.deprecationr   Zutils._tagsr   Zutils.validationr   r   Zutils.fixesr   r   __all__r   r   r   r   rb   r   r   r   r   r   r   r   <module>   sD       u-  
  
  