Filter topics defined as topic-word distribution `topic_word_distrib` across vocabulary `vocab` for a word (pass a
    string) or multiple words/patterns `w` (pass a list of strings). Either run pattern(s) `w` against the list of
    top words per topic (use `top_n` for number of words in top words list) or specify a minimum topic-word probability
    `thresh`, resulting in a list of words above this threshold for each topic, which will be used for pattern matching.
    You can also specify `top_n` *and* `thresh`.
    Set the `match` parameter according to the options provided by `filter_tokens.token_match()` (exact matching, RE or
    glob matching). Use `cond` to specify whether at only *one* match suffices per topic when a list of patterns `w` is
    passed (`cond='any'`) or *all* patterns must match (`cond='all'`).
    By default, this function returns a NumPy array containing the *indices* of topics that passed the filter criteria.
    If `return_words_and_matches` is True, this function additonally returns a NumPy array with the top words for each
    topic and a NumPy array with the pattern matches for each topic.

def filter_topics(w, vocab, topic_word_distrib, top_n=None, thresh=None, match='exact', cond='any', glob_method='match',
                  return_words_and_matches=False):
    """
    Filter topics defined as topic-word distribution `topic_word_distrib` across vocabulary `vocab` for a word (pass a
    string) or multiple words/patterns `w` (pass a list of strings). Either run pattern(s) `w` against the list of
    top words per topic (use `top_n` for number of words in top words list) or specify a minimum topic-word probability
    `thresh`, resulting in a list of words above this threshold for each topic, which will be used for pattern matching.
    You can also specify `top_n` *and* `thresh`.
    Set the `match` parameter according to the options provided by `filter_tokens.token_match()` (exact matching, RE or
    glob matching). Use `cond` to specify whether at only *one* match suffices per topic when a list of patterns `w` is
    passed (`cond='any'`) or *all* patterns must match (`cond='all'`).
    By default, this function returns a NumPy array containing the *indices* of topics that passed the filter criteria.
    If `return_words_and_matches` is True, this function additonally returns a NumPy array with the top words for each
    topic and a NumPy array with the pattern matches for each topic.
    """
    if not w:
        raise ValueError('`w` must be non empty')

    if isinstance(w, str):
        w = [w]
    elif not isinstance(w, (list, tuple, set)):
        raise ValueError('`w` must be either string or list, tuple or set')

    if top_n is None and thresh is None:
        raise ValueError('either `top_n` or `thresh` must be given')

    if cond not in {'any', 'all'}:
        raise ValueError("`cond` must be one of `'any', 'all'`")

    if thresh is None:
        top_words = top_words_for_topics(topic_word_distrib, top_n=top_n, vocab=vocab)
        top_probs = None
    else:
        top_words, top_probs = top_words_for_topics(topic_word_distrib, top_n=top_n, vocab=vocab, return_prob=True)

    found_topic_indices = []
    found_topic_words = []
    found_topic_matches = []
    cond_fn = np.any if cond == 'any' else np.all

    for t_idx, words in enumerate(top_words):
        token_matches = [token_match(x, words, match, glob_method=glob_method) for x in w]
        if top_probs:
            words_p = top_probs[t_idx]
            probs_matches = [sum(words_p[m] >= thresh) > 0 for m in token_matches]
        else:
            probs_matches = [[True]]

        token_matches_comb = np.any(token_matches, axis=1)
        assert len(token_matches_comb) == len(w)

        if cond_fn(token_matches_comb) and cond_fn(probs_matches):
            found_topic_indices.append(t_idx)
            if return_words_and_matches:
                found_topic_words.append(words)
                found_topic_matches.append(np.any(token_matches, axis=0))

    if return_words_and_matches:
        return np.array(found_topic_indices), np.array(found_topic_words), np.array(found_topic_matches)
    else:
        return np.array(found_topic_indices)