You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Polars的大规模数据集NDCG高效计算优化咨询

基于Polars的大规模数据集NDCG高效计算优化咨询

我现在需要在Polars里实现针对超大规模数据集的高效NDCG计算。

NDCG的核心思路是计算DCG和IDCG,这里我先跳过增益部分,只聚焦于折扣项的计算——这部分依赖于理想排序和推荐排序中对应项的排名位置。

我目前遇到的难点在于,如何准确且高效地计算理想列表和推荐列表中交集项的位置。举个例子:

ideal:   a b c d e f
proposed: d b g e h

两者的交集是{b, d, e},对应的理想位置是idx_ideal=[2,4,5](从1开始计数),推荐位置是idx_proposed=[2,1,4]。

我的目标是给包含(user, ideal, proposed)列的DataFrame,添加idx_ideal和idx_proposed列,最终得到的DataFrame结构是(user, ideal, proposed, idx_ideal, idx_proposed)。

我目前的实现思路是先处理理想列表的位置,再用同样的逻辑处理推荐列表,最后将结果合并:

# 先计算理想列表的位置,之后用同样逻辑计算推荐列表的位置再做关联
(
    df
        .explode('ideal')
        .with_columns(idx=pl.int_range(pl.len()).over('user'))
        .filter(pl.col('ideal').is_in(pl.col('proposed')))
        .group_by('user', maintain_order=True)
        .agg(pl.col('idx'))
)

但这种方法会生成一个只包含子集行的额外DataFrame,之后还需要关联回原数据,感觉效率不高。而且接下来我还需要对(idx_ideal, idx_proposed)做展开操作,才能计算每个用户的IDCG、DCG和最终的NDCG。

我觉得可以利用用户数据互相独立的特点,对每行数据单独处理来优化计算,想请教下有没有更优的实现方案?

下面是我用来测试的随机数据生成器:

import polars as pl
import random

num_users = 100_000
min_len = 10
max_len = 200
item_range = 10_000

def generate_user_data():
    length = random.randint(min_len, max_len)
    ideal = random.sample(range(item_range), length)

    length = random.randint(min_len, max_len)
    predicted = random.sample(range(item_range), length)
    
    return ideal, predicted

data = []
for user_id in range(num_users):
    ideal, predicted = generate_user_data()
    data.append({
        'user': user_id,
        'ideal': ideal,
        'proposed': predicted
    })

df = pl.DataFrame(data)
print(df.head())

运行后输出的示例数据如下:

shape: (5, 3)
┌──────┬──────────────────────┬──────────────────────┐
│ user ┆ ideal                ┆ proposed             │
│ ---  ┆ ---                  ┆ ---                  │
│ i64  ┆ list[i64]            ┆ list[i64]            │
╞══════╪══════════════════════╪══════════════════════╡
│ 0    ┆ [9973, 313, … 5733]  ┆ [8153, 3461, … 4602] │
│ 1    ┆ [3756, 9053, … 1014] ┆ [435, 9407, … 6159]  │
│ 2    ┆ [8152, 1615, … 2873] ┆ [5078, 9006, … 8157] │
│ 3    ┆ [6104, 2929, … 2606] ┆ [5110, 790, … 363]   │
│ 4    ┆ [1863, 6801, … 271]  ┆ [5571, 5555, … 5591] │
└──────┴──────────────────────┴──────────────────────┘

备注:内容来源于stack exchange,提问作者Sindbag

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 09:24:35