def intra_inter_distances(X, labels, metric='precomputed'):
    atol = (np.finfo(X.dtype).eps * 100)
    if np.any((np.abs(np.diagonal(X)) > atol)):
        raise ValueError('The precomputed distance matrix contains non-zero elements on the diagonal. Use np.fill_diagonal(X, 0).')
    le = LabelEncoder()
    labels = le.fit_transform(labels)
    n_samples = len(labels)
    label_freqs = np.bincount(labels)
    check_number_of_labels(len(le.classes_), n_samples)
    reduce_func = functools.partial(cluster_dist_reduce, labels=labels, label_freqs=label_freqs)
    results = zip(*pairwise_distances_chunked(X, reduce_func=reduce_func))
    (intra_clust_dists, inter_clust_dists) = results
    intra_clust_dists = np.concatenate(intra_clust_dists)
    inter_clust_dists = np.concatenate(inter_clust_dists)
    return (np.mean(intra_clust_dists), np.mean(inter_clust_dists))
def intra_inter_distances(X, labels, metric='precomputed'):
    atol = (np.finfo(X.dtype).eps * 100)
    if np.any((np.abs(np.diagonal(X)) > atol)):
        raise ValueError('The precomputed distance matrix contains non-zero elements on the diagonal. Use np.fill_diagonal(X, 0).')
    le = LabelEncoder()
    labels = le.fit_transform(labels)
    n_samples = len(labels)
    label_freqs = np.bincount(labels)
    check_number_of_labels(len(le.classes_), n_samples)
    reduce_func = functools.partial(cluster_dist_reduce, labels=labels, label_freqs=label_freqs)
    results = zip(*pairwise_distances_chunked(X, reduce_func=reduce_func))
    (intra_clust_dists, inter_clust_dists) = results
    intra_clust_dists = np.concatenate(intra_clust_dists)
    inter_clust_dists = np.concatenate(inter_clust_dists)
    return (np.mean(intra_clust_dists), np.mean(inter_clust_dists))