def cluster(df: pd.DataFrame, header_prefix: List[str]=None, maxsize: int=20, method: str='single', numeric_cat: List[str]=None, plot=False) -> List[List[str]]:
    '\n    Given an input dataframe, extract clusters of similar headers\n    based on a set of heuristics.\n\n    Args:\n        df: The dataframe to cluster headers from.\n        header_prefix: List of columns to remove before cluster generation.\n        maxsize: The max number of header clusters to generate\n            from the input dataframe.\n        method: Linkage method used to compute header cluster\n            distances. For more information please refer to the scipy\n            docs, https://docs.scipy.org/doc/scipy/reference/generated/scipy.cluster.hierarchy.linkage.html#scipy-cluster-hierarchy-linkage.\n        numeric_cat: A list of fields to define as categorical. The header\n            clustering code will automatically define pandas "object" and\n            "category" columns as categorical. The ``numeric_cat`` parameter\n            may be used to define additional categorical fields that may\n            not automatically get identified as such.\n        plot: Plot header list as a dendogram.\n    '

    def prepare_response(col_list: List[List[str]], prefix: List[str]=None) -> List[List[str]]:
        if (prefix is not None):
            col_list[0] = (prefix + col_list[0])
        return col_list
    if (numeric_cat is None):
        numeric_cat = []
    if (header_prefix is not None):
        try:
            df = df.drop(header_prefix, axis=1)
        except KeyError as err:
            raise ValueError('Header prefixes do not all exist in source DF') from err
    if (df.shape[1] == 1):
        return prepare_response([list(df.columns)], header_prefix)
    corr_matrix = _get_correlation_matrix(df, numeric_cat)
    X = (1 - np.array((1 - abs(corr_matrix))))
    L = sch.linkage(X, method=method)
    Lopt = sch.optimal_leaf_ordering(L, X)
    columns = df.columns
    start = (len(Lopt) - 1)
    clusters = _traverse_node(Lopt, start, maxsize, len(columns))
    col_list = _merge_clusters(clusters, maxsize, columns, Lopt, plot)
    return prepare_response(col_list, header_prefix)
Given an input dataframe, extract clusters of similar headers
based on a set of heuristics.

Args:
    df: The dataframe to cluster headers from.
    header_prefix: List of columns to remove before cluster generation.
    maxsize: The max number of header clusters to generate
        from the input dataframe.
    method: Linkage method used to compute header cluster
        distances. For more information please refer to the scipy
        docs, https://docs.scipy.org/doc/scipy/reference/generated/scipy.cluster.hierarchy.linkage.html#scipy-cluster-hierarchy-linkage.
    numeric_cat: A list of fields to define as categorical. The header
        clustering code will automatically define pandas "object" and
        "category" columns as categorical. The ``numeric_cat`` parameter
        may be used to define additional categorical fields that may
        not automatically get identified as such.
    plot: Plot header list as a dendogram.
def cluster(df: pd.DataFrame, header_prefix: List[str]=None, maxsize: int=20, method: str='single', numeric_cat: List[str]=None, plot=False) -> List[List[str]]:
    '\n    Given an input dataframe, extract clusters of similar headers\n    based on a set of heuristics.\n\n    Args:\n        df: The dataframe to cluster headers from.\n        header_prefix: List of columns to remove before cluster generation.\n        maxsize: The max number of header clusters to generate\n            from the input dataframe.\n        method: Linkage method used to compute header cluster\n            distances. For more information please refer to the scipy\n            docs, https://docs.scipy.org/doc/scipy/reference/generated/scipy.cluster.hierarchy.linkage.html#scipy-cluster-hierarchy-linkage.\n        numeric_cat: A list of fields to define as categorical. The header\n            clustering code will automatically define pandas "object" and\n            "category" columns as categorical. The ``numeric_cat`` parameter\n            may be used to define additional categorical fields that may\n            not automatically get identified as such.\n        plot: Plot header list as a dendogram.\n    '

    def prepare_response(col_list: List[List[str]], prefix: List[str]=None) -> List[List[str]]:
        if (prefix is not None):
            col_list[0] = (prefix + col_list[0])
        return col_list
    if (numeric_cat is None):
        numeric_cat = []
    if (header_prefix is not None):
        try:
            df = df.drop(header_prefix, axis=1)
        except KeyError as err:
            raise ValueError('Header prefixes do not all exist in source DF') from err
    if (df.shape[1] == 1):
        return prepare_response([list(df.columns)], header_prefix)
    corr_matrix = _get_correlation_matrix(df, numeric_cat)
    X = (1 - np.array((1 - abs(corr_matrix))))
    L = sch.linkage(X, method=method)
    Lopt = sch.optimal_leaf_ordering(L, X)
    columns = df.columns
    start = (len(Lopt) - 1)
    clusters = _traverse_node(Lopt, start, maxsize, len(columns))
    col_list = _merge_clusters(clusters, maxsize, columns, Lopt, plot)
    return prepare_response(col_list, header_prefix)