# 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

def value_counts_plus(
    series,
    dropna=False,
    show_top=10,
    sort_others=False,
    style=True,
    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.

    Returns
    -------
    value_counts_df : a pandas.DataFrame showing counts based on the provided arguments        
    """
    series = pd.Series(series)
    series.name = series.name or 'data'
    col = series.name or 'data'
    val_counts = series.value_counts(dropna=dropna)
    if len(val_counts) > show_top:
        val_counts = pd.concat([
            val_counts[:show_top],
            pd.Series(val_counts[show_top:].sum(), index=['Others:'], name=col)])
        if sort_others:                                                
            val_counts = val_counts.sort_values(ascending=False)                                                
        show_top += 1
    count_df = (val_counts
                .to_frame()
                .assign(cum_count=lambda df: df[col].cumsum(),
                        perc=lambda df: df[col].div(df[col].sum()),
                        cum_perc=lambda df: df['perc'].cumsum())
                .reset_index()
                .rename(columns={'index': col, col: 'count'}))
    if not style:
        return count_df.head(show_top)
    return (count_df.
            head(show_top).style
            .format({'count': '{:,}', 'cumsum': '{:,}', 
                     'perc': '{:.1%}',
                     'cum_count': '{:,}',
                     'cum_perc': '{:.1%}'})
            .background_gradient(background_gradient)
            .highlight_null()
            .set_caption(f'<h2>Counts of <b>{series.name}</b></h2>'))

