U
    3d"                     @   s   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Z
dddZdd Zdd Zdd ZG dd dZddddZdS )    wraps)issparse   )check_pandas_support   )
get_config)available_ifN)indexc                C   s   t | rtdt|r<z
| }W n tk
r:   d}Y nX td}t| |jrp|dk	r^|| _|dk	rl|| _| S |j| ||dS )a  Create a Pandas DataFrame.

    If `data_to_wrap` is a DataFrame, then the `columns` and `index` will be changed
    inplace. If `data_to_wrap` is a ndarray, then a new DataFrame is created with
    `columns` and `index`.

    Parameters
    ----------
    data_to_wrap : {ndarray, dataframe}
        Data to be wrapped as pandas dataframe.

    columns : callable, ndarray, or None
        The column names or a callable that returns the column names. The
        callable is useful if the column names require some computation.
        If `columns` is a callable that raises an error, `columns` will have
        the same semantics as `None`. If `None` and `data_to_wrap` is already a
        dataframe, then the column names are not changed. If `None` and
        `data_to_wrap` is **not** a dataframe, then columns are
        `range(n_features)`.

    index : array-like, default=None
        Index for data.

    Returns
    -------
    dataframe : DataFrame
        Container with column names or unchanged `output`.
    z+Pandas output does not support sparse data.Nz$Setting output container to 'pandas')r
   columns)	r   
ValueErrorcallable	Exceptionr   
isinstanceZ	DataFramer   r
   )data_to_wrapr   r
   pd r   =/tmp/pip-unpacked-wheel-zrfo1fqw/sklearn/utils/_set_output.py_wrap_in_pandas_container
   s    "

r   c                 C   sL   t |di }| |kr||  }nt |  d }|dkrDtd| d|iS )a  Get output config based on estimator and global configuration.

    Parameters
    ----------
    method : {"transform"}
        Estimator's method for which the output container is looked up.

    estimator : estimator instance or None
        Estimator to get the output configuration from. If `None`, check global
        configuration is used.

    Returns
    -------
    config : dict
        Dictionary with keys:

        - "dense": specifies the dense container for `method`. This can be
          `"default"` or `"pandas"`.
    _sklearn_output_config_output>   defaultpandasz0output config must be 'default' or 'pandas' got dense)getattrr   r   )method	estimatorZest_sklearn_output_configZdense_configr   r   r   _get_output_configA   s    
r   c                 C   s:   t | |}|d dkst|s"|S t|t|dd|jdS )a  Wrap output with container based on an estimator's or global config.

    Parameters
    ----------
    method : {"transform"}
        Estimator's method to get container output for.

    data_to_wrap : {ndarray, dataframe}
        Data to wrap with container.

    original_input : {ndarray, dataframe}
        Original input of function.

    estimator : estimator instance
        Estimator with to get the output configuration from.

    Returns
    -------
    output : {ndarray, dataframe}
        If the output config is "default" or the estimator is not configured
        for wrapping return `data_to_wrap` unchanged.
        If the output config is "pandas", return `data_to_wrap` as a pandas
        DataFrame.
    r   r   r
   N)r   r
   r   )r   _auto_wrap_is_configuredr   r   get_feature_names_out)r   r   Zoriginal_inputr   Zoutput_configr   r   r   _wrap_data_with_containerc   s    

r    c                    s   t   fdd}|S )z@Wrapper used by `_SetOutputMixin` to automatically wrap methods.c                    sJ    | |f||}t |tr<t|d || f|dd  S t||| S )Nr   r   )r   tupler    )selfXargskwargsr   fr   r   r   wrapped   s    

z$_wrap_method_output.<locals>.wrappedr   )r'   r   r(   r   r&   r   _wrap_method_output   s    r)   c                 C   s    t | dt }t| dod|kS )zReturn True if estimator is configured for auto-wrapping the transform method.

    `_SetOutputMixin` sets `_sklearn_auto_wrap_output_keys` to `set()` if auto wrapping
    is manually disabled.
    _sklearn_auto_wrap_output_keysr   	transform)r   sethasattr)r   auto_wrap_output_keysr   r   r   r      s    
r   c                       s8   e Zd ZdZd fdd	ZeeddddZ  ZS )	_SetOutputMixina\  Mixin that dynamically wraps methods to return container based on config.

    Currently `_SetOutputMixin` wraps `transform` and `fit_transform` and configures
    it based on `set_output` of the global configuration.

    `set_output` is only defined if `get_feature_names_out` is defined and
    `auto_wrap_output_keys` is the default value.
    r+   c                    s   t  jf | t|ts(|d ks(td|d kr<t | _d S ddd}t | _| D ]P\}}t| |rV||krrqV| j	| || j
krqVtt| ||}t| || qVd S )Nz6auto_wrap_output_keys must be None or a tuple of keys.r+   )r+   fit_transform)super__init_subclass__r   r!   r   r,   r*   itemsr-   add__dict__r)   r   setattr)clsr.   r%   Zmethod_to_keyr   keyZwrapped_method	__class__r   r   r3      s*    
z!_SetOutputMixin.__init_subclass__Nc                C   s*   |dkr| S t | dsi | _|| jd< | S )aD  Set output container.

        See :ref:`sphx_glr_auto_examples_miscellaneous_plot_set_output.py`
        for an example on how to use the API.

        Parameters
        ----------
        transform : {"default", "pandas"}, default=None
            Configure output of `transform` and `fit_transform`.

            - `"default"`: Default output format of a transformer
            - `"pandas"`: DataFrame output
            - `None`: Transform configuration is unchanged

        Returns
        -------
        self : estimator instance
            Estimator instance.
        Nr   r+   )r-   r   )r"   r+   r   r   r   
set_output   s    

z_SetOutputMixin.set_output)r0   )	__name__
__module____qualname____doc__r3   r	   r   r<   __classcell__r   r   r:   r   r/      s   	 r/   r0   c                C   sJ   t | dpt | do|dk	}|s$dS t | ds>td|  d| j|dS )a  Safely call estimator.set_output and error if it not available.

    This is used by meta-estimators to set the output for child estimators.

    Parameters
    ----------
    estimator : estimator instance
        Estimator instance.

    transform : {"default", "pandas"}, default=None
        Configure output of the following estimator's methods:

        - `"transform"`
        - `"fit_transform"`

        If `None`, this operation is a no-op.

    Returns
    -------
    estimator : estimator instance
        Estimator instance.
    r+   r1   Nr<   zUnable to configure output for z' because `set_output` is not available.r0   )r-   r   r<   )r   r+   Zset_output_for_transformr   r   r   _safe_set_output   s    



rB   )N)	functoolsr   Zscipy.sparser    r   _configr   Z_available_ifr	   r   r   r    r)   r   r/   rB   r   r   r   r   <module>   s   7
"&I