Pandas逐列以列众数填充用户电影评分矩阵NaN值的实现方法
按电影列用众数填充评分矩阵缺失值的正确实现
原代码的执行风险
编写的rating.apply(lambda x: x.fillna(x.mode().item())) 逻辑方向正确,但存在两个边界场景下的执行报错问题:
- 当某一列存在多个并列众数时,
x.mode()会返回包含所有众数的序列,而非单个值,此时调用.item()会直接抛出ValueError,无法将长度大于1的序列转为单个标量 - 当某一电影列没有任何有效评分(全为NaN)时,
x.mode()会返回空序列,此时调用.item()会抛出IndexError
高效正确实现方案
针对大规格的用户-电影评分矩阵,优先使用pandas原生批量计算逻辑,避免逐列apply带来的性能损耗:
# 1. 一次性计算所有电影列的众数,取首行值作为每列的填充值,自动适配多众数场景 col_mode = rating.mode().iloc[0] # 2. 按列名匹配对应众数,批量填充所有NaN值 rating_filled = rating.fillna(col_mode)
逻辑说明
rating.mode()原生支持按列维度计算,返回的DataFrame每一列存储了该列所有频次最高的众数,按出现频次排序,取.iloc[0]即可拿到每列优先级最高的众数值- 相比逐列遍历的apply写法,批量计算的方式在百万级单元格的大矩阵下,运行速度会提升数倍
边界场景适配版本
如果存在某电影列全为NaN的特殊场景,可增加空值判断逻辑,避免程序中断:
# 计算每列众数,若某列无有效评分则保留原NaN值 col_mode = rating.mode() fill_values = col_mode.iloc[0] if not col_mode.empty else None rating_filled = rating.fillna(fill_values)
注意:连续评分场景下出现严格并列众数的概率较低,上述代码默认取并列众数中排序最靠前的数值,若业务规则要求对并列众数做特殊处理(比如取所有众数的均值、取最高评分值),可在计算
col_mode时自定义取值逻辑。
内容的提问来源于stack exchange,提问作者Th3LLY
相关产品推荐
相关产品推荐

