解决Movielens构建稀疏评分矩阵的只读数组错误及实现方案
解决「ValueError: putmask: output array is read-only」错误并构建用户-电影评分矩阵
错误根源
这个错误本质是你在尝试修改只读状态的numpy数组——要么是数据集加载后未转为可写对象,要么是操作了pandas返回的数组视图而非副本。新版pandas可以通过内置方法直接绕过这类问题,同时高效完成评分矩阵的构建。
完全可以用pivot_table实现矩阵构建
这是新版pandas中构建用户-电影评分矩阵的推荐方案,代码简洁且从根源避免只读数组问题,具体操作如下:
代码示例
假设你的Movielens评分数据已加载为包含userId、movieId、rating三列的DataFrameratings_df:
import pandas as pd # 加载Movielens评分数据(替换为你的实际文件路径) ratings_df = pd.read_csv('ratings.csv') # 用pivot_table构建评分矩阵 rating_matrix = pd.pivot_table( ratings_df, values='rating', index='userId', columns='movieId', fill_value=0 # 未评分的稀疏位置填充0,也可替换为np.nan ) # 若需转为可写numpy数组(可选) rating_matrix_np = rating_matrix.values.copy() # copy()确保数组可写,规避只读问题
参数说明
values='rating':指定填充到矩阵中的核心值为用户评分index='userId':将用户ID设为矩阵的行索引columns='movieId':将电影ID设为矩阵的列索引fill_value:自定义未评分位置的填充值,按需选择0或缺失值标记
修复原代码只读数组问题的方案
如果坚持原有构建逻辑(基于numpy操作),只需确保操作的数组处于可写状态:
import pandas as pd import numpy as np ratings_df = pd.read_csv('ratings.csv') # 获取唯一用户/电影ID列表 user_ids = ratings_df['userId'].unique() movie_ids = ratings_df['movieId'].unique() # 直接初始化可写空矩阵(核心:避免使用只读数组) rating_matrix = np.zeros((len(user_ids), len(movie_ids)), dtype=np.float64) # 建立ID到矩阵索引的映射 user_id_map = {uid: idx for idx, uid in enumerate(user_ids)} movie_id_map = {mid: idx for idx, mid in enumerate(movie_ids)} # 填充评分数据 for _, row in ratings_df.iterrows(): rating_matrix[user_id_map[row['userId']], movie_id_map[row['movieId']]] = row['rating']
大内存优化方案(可选)
针对超大规模数据集,可结合scipy.sparse构建稀疏矩阵,既规避只读问题又大幅节省内存:
from scipy.sparse import csr_matrix # 将用户/电影ID转为类别编码 user_codes = ratings_df['userId'].astype('category').cat.codes movie_codes = ratings_df['movieId'].astype('category').cat.codes # 构建CSR格式稀疏矩阵 sparse_rating_matrix = csr_matrix( (ratings_df['rating'], (user_codes, movie_codes)) )
内容的提问来源于stack exchange,提问作者supreet singh
相关产品推荐
相关产品推荐

