电影评分数据报错:TypeError: list indices must be integers or slices, not tuple
嘿,我来帮你拆解这个问题!这个错误的根源其实很清晰,咱们一步步来理清楚:
错误原因
报错出现在这一行:
nb_users = int(max(max(training_set[:,0]), max(test_set[:,0])))
提示TypeError: list indices must be integers or slices, not tuple,这说明此时你的training_set已经是Python列表,而不是NumPy数组了。Python列表不支持[:,0]这种NumPy风格的多维切片语法——列表只能用整数(比如[0])或者单维度切片(比如[1:5]),不能用元组形式的索引。
为什么会出现这种情况?看你的代码顺序:你先计算nb_users和nb_movies,然后定义convert函数,接着把training_set和test_set转换成了列表(training_set = convert(training_set))。如果是在Jupyter Notebook这类环境中重复运行了这段代码,第二次执行时,training_set已经被覆盖成列表了,再用NumPy的索引方式自然就报错了。
解决方案
1. 避免覆盖原NumPy数组
不要把转换后的列表赋值给原来的数组变量,给转换后的结果起个新名字:
# 先计算用户和电影数量(此时training_set/test_set还是NumPy数组) nb_users = int(max(training_set[:,0].max(), test_set[:,0].max())) nb_movies = int(max(training_set[:,1].max(), test_set[:,1].max())) def convert(data): new_data = [] # 修复注释格式,加上# # expects that. 1 list per user for id_users in range(1, nb_users + 1): id_movies = data[:,1][data[:,0] == id_users] id_ratings = data[:,2][data[:,0] == id_users] ratings = np.zeros(nb_movies) ratings[id_movies - 1] = id_ratings new_data.append(list(ratings)) return new_data # 用新变量存储转换后的列表,不覆盖原数组 training_set_list = convert(training_set) test_set_list = convert(test_set)
2. 优化最大值计算
另外,你可以简化最大值的计算,不用嵌套max,直接用NumPy数组的.max()方法:
nb_users = int(max(training_set[:,0].max(), test_set[:,0].max())) nb_movies = int(max(training_set[:,1].max(), test_set[:,1].max()))
这样代码更简洁,效率也更高。
3. 确保代码执行顺序正确
如果必须复用变量,那一定要保证先计算nb_users和nb_movies,再执行convert函数转换数组,并且不要重复执行这段代码(或者在执行前重新加载原始的NumPy数组)。
总结
核心问题就是变量类型不匹配:你想用NumPy的索引语法操作Python列表,导致了报错。只要保证计算用户/电影数量时,操作的是原始NumPy数组,并且不覆盖原数组,就能解决这个问题啦!
内容的提问来源于stack exchange,提问作者LaLaTi

