def summary(data: pd.DataFrame) -> pd.DataFrame:
    """

    :param data:
    :return:
    """
    # types
    df = pd.DataFrame(data.dtypes).rename(columns={0: 'Types'})

    # set
    df = pd.merge(
        df, pd.DataFrame(
            data.apply(lambda se: str(sorted(set(se.dropna())))[:1000])
        ).rename(columns={0: 'Set Values'}),
        left_index=True, right_index=True
    )

    # count set
    df = pd.merge(
        df, pd.DataFrame(
            data.apply(lambda se: se.dropna().unique().shape[0])
        ).rename(columns={0: 'Count Set'}),
        left_index=True, right_index=True
    )

    # total observations
    df = pd.merge(
        df, pd.DataFrame(
            data.count()
        ).rename(columns={0: '# Observations'}),
        left_index=True, right_index=True
    )

    # total of nan
    df = pd.merge(
        df, pd.DataFrame(data.isnull().sum()).rename(columns={0: '# NaN'}),
        left_index=True, right_index=True
    )
    return df
def summary ( data : pd . DataFrame ) -> pd . DataFrame : df = pd . DataFrame ( data . dtypes ) . rename ( columns = { 0 : 'Types' } ) df = pd . merge ( df , pd . DataFrame ( data . apply ( lambda se : str ( sorted ( set ( se . dropna ( ) ) ) ) [ : 1000 ] ) ) . rename ( columns = { 0 : 'Set Values' } ) , left_index = True , right_index = True ) df = pd . merge ( df , pd . DataFrame ( data . apply ( lambda se : se . dropna ( ) . unique ( ) . shape [ 0 ] ) ) . rename ( columns = { 0 : 'Count Set' } ) , left_index = True , right_index = True ) df = pd . merge ( df , pd . DataFrame ( data . count ( ) ) . rename ( columns = { 0 : '# Observations' } ) , left_index = True , right_index = True ) df = pd . merge ( df , pd . DataFrame ( data . isnull ( ) . sum ( ) ) . rename ( columns = { 0 : '# NaN' } ) , left_index = True , right_index = True ) return df
:param data:
    :return: