def ndcg(truth, recommend, k=None):
    """Normalized Discounted Cumulative Grain (NDCG).

    Args:
        truth (numpy 1d array): Set of truth samples.
        recommend (numpy 1d array): Ordered set of recommended samples.
        k (int): Top-k items in `recommend` will be recommended.

    Returns:
        float: NDCG.

    """
    if k is None:
        k = len(recommend)

    def idcg(n_possible_truth):
        res = 0.
        for n in range(n_possible_truth):
            res += 1. / np.log2(n + 2)
        return res

    dcg = 0.
    for n, r in enumerate(recommend[:k]):
        if r not in truth:
            continue
        dcg += 1. / np.log2(n + 2)

    res_idcg = idcg(np.min([truth.size, k]))
    if res_idcg == 0.:
        return 0.
    return dcg / res_idcg
Normalized Discounted Cumulative Grain (NDCG).

    Args:
        truth (numpy 1d array): Set of truth samples.
        recommend (numpy 1d array): Ordered set of recommended samples.
        k (int): Top-k items in `recommend` will be recommended.

    Returns:
        float: NDCG.