Return data frame with all possible combinations
    of the values in the columns

def unique_combs(df):
    """
    Return data frame with all possible combinations
    of the values in the columns
    """
    # List of unique values from every column
    lst = (x.unique() for x in (df[c] for c in df))
    rows = list(itertools.product(*lst))
    _df = pd.DataFrame(rows, columns=df.columns)

    # preserve the column dtypes
    for col in df:
        _df[col] = _df[col].astype(df[col].dtype, copy=False)
    return _df