使用df.at设置DataFrame值遇ValueError,如何修正商品推荐函数?
问题分析与解决方案
错误核心原因
df.at赋值类型错误:df.at[row, col]仅支持单个标量值赋值,但你直接传入了余弦相似度返回的数组(哪怕是单元素数组),触发了"equal len keys and value"的报错。- 特征维度不匹配:
point_1是(1,2)的二维数组,point_2是(2,)的一维数组,计算余弦相似度时维度不兼容,会导致结果格式异常。 - 遍历效率低下:循环逐行赋值
dist列的写法不仅慢,还容易触发索引相关的问题。
修改后的函数示例
先基于你的需求还原并修正基础版本:
from sklearn.metrics.pairwise import cosine_similarity import pandas as pd def recommend_top5(input_name, df): # 获取目标商品的t-SNE特征,形状(1,2) target_point = df.loc[df['name'] == input_name, ['x', 'y']].values # 初始化dist列 df['dist'] = 0.0 for idx, row in df.iterrows(): # 提取当前商品特征并重塑为(1,2),和目标特征维度统一 curr_point = row[['x', 'y']].values.reshape(1, 2) # 计算余弦相似度,结果为(1,1)数组 sim_score = cosine_similarity(target_point, curr_point) # 提取标量值赋值给dist列,避免传入可迭代对象 df.at[idx, 'dist'] = sim_score.item() # 按相似度降序取前5(余弦相似度越接近1越相似) return df.sort_values(by='dist', ascending=False).head(5)
更高效的矢量化优化版本
完全去掉循环,用广播机制批量计算,速度提升明显:
from sklearn.metrics.pairwise import cosine_similarity import pandas as pd def recommend_top5(input_name, df): # 获取目标商品的t-SNE特征 target_point = df.loc[df['name'] == input_name, ['x', 'y']].values # 提取所有商品的特征矩阵,形状(n,2) all_points = df[['x', 'y']].values # 批量计算所有相似度,结果为一维数组(n,) all_sims = cosine_similarity(target_point, all_points)[0] # 直接赋值dist列,无需循环 df['dist'] = all_sims # 返回相似度最高的5款商品 return df.sort_values(by='dist', ascending=False).head(5)
关键修改点
- 统一特征维度:把
point_2从(2,)重塑为(1,2),确保和point_1维度一致,让余弦相似度计算返回格式稳定。 - 提取标量赋值:用
sim_score.item()或sim_score[0][0]从相似度数组中取出单个数值,再传给df.at。 - 矢量化替代循环:利用sklearn的批量计算能力,避免逐行遍历,既解决报错又提升效率。
内容的提问来源于stack exchange,提问作者itsanhtuanho
相关产品推荐
相关产品推荐

