我有一个DataFrame(d1
)与(index, features)
和第二个(d2
)具有相同的列。
features
是Seq[Double]
,index
是String
。
d1
大约有一百万行,d2
可能介于40到10,000之间。
我想最后得到(index, CosineSimilarities)
CosineSimilarities
的数据框:对于每个d1
行,Seq[Double]
等于此行之间的余弦相似度以及d2
的每一行。因此CosineSimilarities
长度应等于d2
行数。
我的第一种方法是使用DenseMatrix
和IndexedRowMatrix
以及d1.multiply(d2.transpose)
。但是很难将结果映射回index
,当d2
变大时,任务中断。
我的第二种方法是:
d1
.cartesian(d2)
.repartition(n)
.map { case ((d1index, d1features), (_, d2features)) =>
(d1index, myCosineSimilarityMethod(d1features, d2features))
}
但这很痛苦。
我的第三种方法是Broadcast
d2
并按行逐行:
d1
.mapValues { d1features =>
d2broadcasted
.value
.map { case (_, d2features) =>
myCosineSimilarityMethod(d1features, d2features)
}
.toSeq
)
}
它起作用,它比approach2更具可扩展性和更快,但不如approach1快。
还有其他更好的方法吗?
修改
我有想法计算d2
的中心,然后计算每个d1
到此中心之间的距离。那会有用吗?有没有办法获得数据帧的质心?