def get_canonical_correlations(dataframe, column_types):
    '''
    computes the correlation coefficient between each distinct pairing of columns
    preprocessing note:
        any rows with missing values (in either paired column) are dropped for that pairing
        categorical columns are replaced with one-hot encoded columns
        any columns which have only one distinct value (after dropping missing values) are skipped
    returns a list of the pairwise canonical correlation coefficients
    '''

    def preprocess(series):
        if column_types[series.name] == 'CATEGORICAL':
            series = pd.get_dummies(series)
        array = series.values.reshape(series.shape[0], -1)
        return array

    if dataframe.shape[1] < 2:
        return []

    correlations = []
    skip_cols = set()
    for col_name_i, col_name_j in itertools.combinations(dataframe.columns, 2):
        if col_name_i in skip_cols or col_name_j in skip_cols:
            correlations.append(0)
            continue

        df_ij = dataframe[[col_name_i, col_name_j]].dropna(axis=0, how="any")
        col_i = df_ij[col_name_i]
        col_j = df_ij[col_name_j]

        if np.unique(col_i).shape[0] <= 1:
            skip_cols.add(col_name_i)
            correlations.append(0)
            continue
        if np.unique(col_j).shape[0] <= 1:
            skip_cols.add(col_name_j)
            correlations.append(0)
            continue

        col_i = preprocess(col_i)
        col_j = preprocess(col_j)

        col_i_c, col_j_c = CCA(n_components=1).fit_transform(col_i,col_j)

        if np.unique(col_i_c).shape[0] <= 1 or np.unique(col_j_c).shape[0] <= 1:
            c = 0
        else:
            c = np.corrcoef(col_i_c.T, col_j_c.T)[0,1]
        correlations.append(c)

    return correlations