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

直接使用DataFrame的id列构造scipy.csr_matrix时出现索引越界错误的原因解析

DataFrame的id列构造scipy.csr_matrix时出现索引越界错误的原因解析

嘿,这个问题我之前也碰到过,核心是你没搞清楚scipy的CSR矩阵对索引的硬性要求~咱们一步步拆解:

两种构造方式的核心差异

首先明确一个关键规则:CSR矩阵要求传入的行/列索引必须是基于0的连续整数,而且最大值绝对不能超过你指定的shape对应维度的大小减一。

  • 能正常运行的X_works:你先把原始的user_id和item_id映射成了从0开始的连续索引(user_idx和item_idx)。比如item_idx的取值范围是0到M-1(M是item唯一值的数量),刚好匹配你指定的shape=(M,N)的第一维度大小,所以索引完全不会越界。
  • 报错的X_doesnt:你直接用了原始的item_id和user_id作为索引。这里的坑在于:原始id虽然是唯一的,但它们的取值范围不一定是0到M-1。比如你的测试代码里,item_id是np.random.randint(0,100,300),这意味着可能出现99这个值,但df["item_id"].nunique()得到的M可能只有97(随机生成大概率会漏掉几个数)。这时候你指定shape=(M,N),矩阵的行维度只有97,行索引最大只能是96,但你的item_id里有99,自然就触发了index 99 exceeds matrix dimension 97的错误。

为什么“id映射到唯一名称数量”还会报错?

你提到“id被映射到正好唯一名称的数量”,但这里的误解在于:原始id的最大值 ≠ 唯一值数量 - 1。比如你的item_id范围是0到100,共101个可能值,随机生成300条数据后,unique的数量可能是97,但最大的item_id依然可能是99,这时候99 > 97-1=96,必然越界。原始id的取值范围和唯一值数量是完全两回事:前者是id的数值区间,后者是不同id的个数。

怎么解决?

有两种可行方案:

  • 继续用你已经实现的映射方法:把原始id转成从0开始的连续索引,确保索引最大值正好对应维度大小减一,完美匹配shape参数,这也是最节省内存的方式。
  • 如果一定要直接用原始id,那shape的维度需要设为max(原始id)+1,而不是nunique()。但这种方式会产生大量空行/列(如果原始id不连续的话),非常浪费内存,只适合id本身就是连续0-based的场景。

比如在你的测试代码里,把X_doesnt的shape改成(df["item_id"].max()+1, df["user_id"].max()+1),它就能正常运行,但矩阵的大小会比X_works大很多,因为包含了那些没有对应数据的id行/列。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 18:00:28