How NDCG is calculated
Discounted cumulative gain. Each result at position i earns a gain from its relevance grade, and that gain is divided by log2(i + 1). Position 1 keeps its full gain (discount 1.0), position 2 keeps 63.1%, position 3 keeps 50%, and position 10 keeps only 28.9%. Summing the discounted gains down to the cutoff k gives DCG@k.
Normalization. DCG on its own depends on how many relevant documents a query has, so it cannot be averaged across queries. NDCG divides DCG@k by IDCG@k, the DCG of the best possible ordering of the judged grades. The result lies between 0 and 1, where 1 means no reordering could improve the top k.
Worked example. For grades 3, 2, 3, 0, 1, 2 with linear gain, DCG@6 = 3 + 1.262 + 1.5 + 0 + 0.387 + 0.712 = 6.861. Sorting those same six grades gives 3, 3, 2, 2, 1, 0 and IDCG@6 = 7.141, so NDCG@6 = 0.9608, which matches scikit-learn ndcg_score.