我有一个pandas数据框(交互数据框),列为用户、项目、评分。
Ratings ItemID UserID1 1172952 A741 1178735 1764 341785 70C3 136771 67E2 1178883 383
假设我还有两个数据框,分别有200个用户和1000个项目。问题在于在交互数据框中,我需要每个用户和每个项目组合的评分。如果在交互数据框中某个用户和项目的组合没有交互记录,则评分为0。
我尝试使用以下循环来解决这个问题:
item_ids = np.repeat(item_data.id.values, len(user_data.id.values))user_ids = np.tile(user_data.id.values, len(item_data.id.values))ratings = np.empty([len(item_ids)])for i in range(len(ratings)): inter = interactions.loc[(interactions['UserID'] == user_ids[i]) & (interactions["ItemID"] == item_ids[i]), "Ratings"] if not inter.empty: ratings[i] = inter.values[0] else: ratings[i] = 0interactions = np.stack((ratings, item_ids, user_ids), axis=-1)
但对于只有30,000行的评分数组,完成这个操作需要40秒。有什么快速的方法可以做到这一点吗?谢谢帮助。
回答:
你对问题的解释有点草率,但我觉得你需要的是这个:
interactions.set_index(['ItemID','UserID'])\ .unstack().fillna(0).astype(int).stack()\ .reset_index()
这段代码创建了一个用户和项目的矩形表,用零填充空缺,并将表转换回一个“高”向量。输出如下:
ItemID UserID Ratings0 136771 176 01 136771 383 02 136771 67E 33 136771 70C 04 136771 A74 05 341785 176 06 341785 383 07 341785 67E 08 341785 70C 49 341785 A74 010 1172952 176 0....
我假设每个项目和每个用户(但不是它们的组合!)在interaction
表中至少被引用一次。如果不是这样,可能需要与另外两个表进行merge
操作。