此处的关键是创建productId的笛卡尔积。参见下面的代码,
方法1(适用于较小的数据集)
result=(main.drop_duplicates(['productId','userId']) .assign(cartesian_key=1) .pipe(lambda x:x.merge(x,on='cartesian_key')) .drop('cartesian_key',axis=1) .loc[lambda x:(x.productId_x!=x.productId_y) & (x.userId_x==x.userId_y)] .groupby(['productId_x','productId_y']).size() .div(data['userId'].nunique()))resultProd1 prod2 0.75Prod1 prod3 0.75Prod1 prod4 0.75Prod1 prod5 0.5prod2 Prod1 0.75prod2 prod3 0.5prod2 prod4 0.5prod2 prod5 0.25prod3 Prod1 0.75prod3 prod2 0.5prod3 prod4 0.5prod3 prod5 0.5prod4 Prod1 0.75prod4 prod2 0.5prod4 prod3 0.5prod4 prod5 0.5prod5 Prod1 0.5prod5 prod2 0.25prod5 prod3 0.5prod5 prod4 0.5方法2
result = (df.groupby(['productId','userId']).size() .clip(upper=1) .unstack() .assign(key=1) .reset_index() .pipe(lambda x:x.merge(x,on='key')) .drop('key',axis=1) .loc[lambda x:(x.productId_x!=x.productId_y)] .set_index(['productId_x','productId_y']) .pipe(lambda x:x.set_axis(x.columns.str.split('_',expand=True),axis=1,inplace=False)) .swaplevel(axis=1) .pipe(lambda x:(x['x']+x['y'])) .fillna(0) .div(2) .mean(axis=1))


