我有两个数据框,一个用于用户配置文件,另一个用于项目配置文件。
df_client = sqlContext.createDataFrame([('c1',0,1,3),('c2',1,0,3)], ['client_id','col1','col2','col3'])
df_item = sqlContext.createDataFrame([('it1',0,1,3),('it2',1,0,3)], ['item_id','col1','col2','col3'])
我想计算用户和项目之间的余弦相似度,并获得这样的最终数据框:
df_final.show()
client_id item_id distance
0 c1 it1 0
1 c1 it2 0.1
2 c2 it1 0.1
3 c2 it2 0
但实际上有1100万用户,150个项目和150列。 所以我开发了三个解决方案,但每个解决方案都需要花费一些时间。
解决方案的一个例子:
list_item= df_item.rdd.collect()
def cosine_distance(v):
list_item_distance = []
for row in list_item:
distance = round(float(cosine(np.array(v[1:]),np.array(row[1:]))),4)
list_item_distance.append((v["client_id"],row["item_id"],distance))
return list_item_distance
rdd_final = df_client.rdd.map(lambda row: cosine_distance(row))
list_final = rdd_final.reduce(lambda x,y: x+y)
但减少是长期
问题是获得像dataframe这样的结果吗? 有人有解决方案快速实现这项工作吗?
答案 0 :(得分:0)
我要做的第一件事就是将列转换为数组。由于没有直接的方法,您可以执行df.create_map(colnames)将列转换为地图,然后选择一个订单并创建一个udf以使其成为一个数组。
接下来我将df标记为广播(150行,约150列不太大)并进行连接。这可能是最长的部分。
然后我将取两个数组并计算它们之间的余弦距离