如何计算Pandas DataFrame中推荐列表相似度并解决KeyError报错
报错原因
你遇到的KeyError: 0是因为你用range(df.shape[0])生成的0、1、2...整数序列作为行标签,通过loc访问DataFrame行,但你的DataFrame索引不是默认的连续整数(比如你提前做过行过滤、删除操作,或者将user_id列设为了索引),loc是按标签取值的,找不到0这个标签就会抛出错误。
正确实现方案
推荐用apply方法实现批量计算,比循环遍历性能高很多,尤其适合大型DataFrame,代码也更简洁。
步骤1:定义相似度计算函数
def calc_overlap_ratio(actual_list, rec_list): set_actual = set(actual_list) set_rec = set(rec_list) # 交集长度除以actual列表长度,保留两位小数,和你给出的示例输出格式对齐 return round(len(set_actual & set_rec) / len(set_actual), 2) # 如果需要输出百分比数值(如66代替0.66),把返回值改成: # return round(len(set_actual & set_rec) / len(set_actual) * 100, 2)
步骤2:批量计算所有策略列的相似度
# 指定要对比的推荐策略列 rec_cols = ["predicted", "popular", "random"] for col in rec_cols: df[f"{col}_ratio"] = df.apply(lambda row: calc_overlap_ratio(row["actual"], row[col]), axis=1)
步骤3:计算各策略的整体平均相似度
# 直接取对应列求均值即可 mean_ratio = df[[f"{col}_ratio" for col in rec_cols]].mean() print(mean_ratio)
如果你坚持用循环实现,修改遍历逻辑即可
不要遍历range(df.shape[0]),直接遍历DataFrame的实际索引值:
rec_cols = ["predicted", "popular", "random"] for idx in df.index: actual = df.loc[idx, "actual"] len_actual = len(set(actual)) for col in rec_cols: rec = df.loc[idx, col] overlap_len = len(set(actual) & set(rec)) df.loc[idx, f"{col}_ratio"] = round(overlap_len / len_actual, 2)
注意事项
- 提前确认
actual列没有空列表,避免出现除以0的报错 - 如果列表里有重复元素需要去重再计算,直接在函数里调整集合转换逻辑即可
内容的提问来源于stack exchange,提问作者futuredataengineer
相关产品推荐
相关产品推荐

