You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何高效生成Pandas中用户未购买商品的数据结构?

高效生成用户未购买商品的数据结构(基于Pandas)

现有如下格式的Pandas DataFrame:

user_id, item_id
0, 0
0, 1
1, 1
2, 1
2, 2
3, 0

每一行代表user_id对应的用户购买了item_id对应的商品(比如用户0购买了商品0和1)。我们需要生成一个存储用户未购买商品的数据结构,示例的预期结果为:

0: 2
1: 0, 2
2: 0
3: 1, 2

你提到的朴素循环实现虽然逻辑简单,但在处理大型DataFrame时会因为逐用户切片查询导致速度极慢:

missing = dict()
all_items = set(df['item_id'].unique())
for user in df['user_id'].unique():
    user_items = set(df[df['user_id'] == user]['item_id'].values)
    missing_items = all_items.difference(user_items)
    missing[user] = missing_items

高效实现方案

下面两种方案都利用Pandas的矢量化操作替代循环,大幅提升处理效率:

方案1:笛卡尔积补集法

通过生成用户-商品的全量组合,再筛选出原始数据中不存在的组合,最后按用户分组:

import pandas as pd

# 生成所有用户和所有商品的全量组合
all_users = df['user_id'].unique()
all_items = df['item_id'].unique()
full_pairs = pd.MultiIndex.from_product([all_users, all_items], names=['user_id', 'item_id']).to_frame(index=False)

# 筛选出未购买的用户-商品对
purchased_pairs = df[['user_id', 'item_id']].drop_duplicates()
missing_pairs = full_pairs.merge(purchased_pairs, on=['user_id', 'item_id'], how='left', indicator=True)
missing_pairs = missing_pairs[missing_pairs['_merge'] == 'left_only'].drop(columns='_merge')

# 整理成目标字典格式,可选排序保证和示例结果一致
missing = missing_pairs.groupby('user_id')['item_id'].apply(sorted).to_dict()

方案2:交叉表布尔筛选法

利用交叉表生成用户-商品的购买矩阵,直接筛选未购买的商品列:

# 生成用户×商品的购买状态矩阵(1表示已购买,0表示未购买)
purchase_matrix = pd.crosstab(df['user_id'], df['item_id'])

# 对每个用户筛选出未购买的商品,转成字典
missing = purchase_matrix.apply(lambda row: purchase_matrix.columns[row == 0].tolist(), axis=1).to_dict()
# 可选排序
missing = {user: sorted(items) for user, items in missing.items()}

效率说明

  • 朴素循环的核心问题是多次重复切片查询DataFrame,时间复杂度随用户数和商品数线性增长,大型数据集下性能极差
  • 矢量化方案依托Pandas底层的C级运算优化,避免了循环中的重复IO和查询操作,处理百万级用户-商品数据时,效率能提升数十倍甚至上百倍

内容的提问来源于stack exchange,提问作者Ach113

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 19:52:46