# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/00_value_counts_plus.ipynb.

# %% auto 0
__all__ = ['value_counts_plus']

# %% ../nbs/00_value_counts_plus.ipynb 3
import pandas as pd

# %% ../nbs/00_value_counts_plus.ipynb 4
def value_counts_plus(
    series,
    dropna=False,
    show_top=10,
    sort_others=False,
    style=True,
    size=10,
    thousands=',',
    decimal='.',
    name='data',
    background_gradient='cividis'):
    """
    Provide a few ways of showing counts of values of items in ``series``.

    Parameters
    ----------
    series : pandas Series or list
        A sequence of items to count.
    dropna : bool
        Whether or not to drop missing values.
    show_top : int
        How many of the top rows to display.
    sort_others : bool
        Whether or not to place "Others" in the bottom (default) or in its
        sorted order position.
    style : bool
        Whether or not to style values for easier reading. If set to ``True``
        the result would not be a DataFrame, and cannot be further manipulated.
        Set the value to ``False`` to get aDataFrame as the return value.
    size : int
        The size in points of the font of the table. This results in the whole
        table being resized.
    thousands : str
        The character to use to separate thousands if `style=True`. Defaults to
        `,` but you can change to `.` or space, or any oher character you want.
    decimal : str
        The character to use to display decimal number if `style=True`. Defaults to
        `.` but you can change to `,`or any oher character you want.

    name : str
        The name of the column that you want displayed in the final table. It
        appears in the caption and defaults to "data".
    background_gradient: str
        The name of the color map to be used as the gradient. Many color maps
        are available: cividis, viridis, copper, cool, magma, and more. You can
        reverse the color by appending _r to the end of the colormap name
        cividis_r for example. Enter a random string to get an error message
        with all available colormaps.

    Returns
    -------
    value_counts_df : pandas.io.formats.style.Styler
        A DataFrame showing counts based on the provided arguments
    """
    final_col_names = ['count', 'cum_count', 'perc', 'cum_perc']
    if name in final_col_names:
        raise ValueError(f"Please make sure you use a name other than {final_col_names}")
    val_counts = pd.Series(series).rename(name).value_counts(dropna=dropna).reset_index()
    val_counts.columns = [name, 'count']
    if len(val_counts) > show_top:
        others_df = pd.DataFrame({
            name: ['Others:'],
            'count': val_counts[show_top:]['count'].sum()
            }, index=[show_top])
        val_counts = pd.concat([
            val_counts[:show_top],
            others_df
        ])
        if sort_others:
            val_counts = val_counts.sort_values(by=['count'], ascending=False)

    count_df = (val_counts
                .assign(
                    cum_count=lambda df: df['count'].cumsum(),
                    perc=lambda df: df['count'].div(df['count'].sum()),
                    cum_perc=lambda df: df['perc'].cumsum())
                )
    if not style:
        return count_df
    count_df.index = range(1, len(count_df)+1)
    count_df.columns = [name, 'count', 'cum. count', '%', 'cum. %']
    return (count_df
            .style
            .format({'count': '{:>,}',
                     'cum. count': '{:>,}',
                     '%': '{:>.1%}',
                     'cum. %': '{:>.1%}'},
                    thousands=thousands,
                    decimal=decimal)
            .background_gradient(background_gradient)
            .highlight_null()
            .set_caption(f'<h2>Counts of <b>{name}</b></h2>')
            .set_table_attributes(f'style=font-size:{size}pt;'))

