我有model.productFeatures()
的RDD,它以(id, array("d", (...)))
的形式返回RDD。例如:
(1, array("d", (0, 1, 2)))
(2, array("d", (4, 3, 2)))
(3, array("d", (5, 3, 0)))
...
我想计算每个数组之间的成对相关性,然后返回每个id
另一个id
,其数组具有最高的相关性。
答案 0 :(得分:1)
你需要的第一件事是得到所有元素对,除了“对角线”,它们是相同的。
>>> rdd.cartesian(rdd).filter(lambda (x, y): x != y).collect()
[((1, array('d', [0.0, 1.0, 2.0])), (2, array('d', [4.0, 3.0, 2.0]))),
((1, array('d', [0.0, 1.0, 2.0])), (3, array('d', [5.0, 3.0, 0.0]))),
((2, array('d', [4.0, 3.0, 2.0])), (1, array('d', [0.0, 1.0, 2.0]))),
((3, array('d', [5.0, 3.0, 0.0])), (1, array('d', [0.0, 1.0, 2.0]))),
((2, array('d', [4.0, 3.0, 2.0])), (3, array('d', [5.0, 3.0, 0.0]))),
((3, array('d', [5.0, 3.0, 0.0])), (2, array('d', [4.0, 3.0, 2.0])))]
然后是一个计算相关性的函数,并重新排列以准备最后一步。让我们假设“相关性”是指numpy.correlate
所做的事情。
def corr_pair(((id1, a1), (id2, a2))):
return id1, (id2, np.correlate(a1, a2)[0])
>>> rdd.cartesian(rdd).filter(lambda (p1, p2): p1 != p2).map(corr_pair).collect()
[(1, (2, 7.0)), (1, (3, 3.0)), (2, (1, 7.0)), (3, (1, 3.0)), (2, (3, 29.0)), (3, (2, 29.0))]
要获得与每个第一个ID具有最大相关性的第二个ID,您可以使用reduceByKey
并始终保持较大的ID:
def keep_higher((id1, c1), (id2, c2)):
if c1 > c2:
return id1, c1
else:
return id2, c2
>>> rdd.cartesian(rdd).filter(lambda (x, y): x != y).map(corr_pair).reduceByKey(keep_higher).collect()
[(1, (2, 7.0)), (2, (3, 29.0)), (3, (2, 29.0))]