【问题标题】:Compare each value of one RDD to each key/value pair of another RDD将一个 RDD 的每个值与另一个 RDD 的每个键/值对进行比较
【发布时间】:2016-01-26 20:16:08
【问题描述】:

这已经困扰了我一段时间,我确信我很无脑。

我有两个键/值对的 RDD,对应一个名称和相关的稀疏向量:

RDDA = [ (nameA1, sparsevectorA1), (nameA2, sparsevectorA2), (nameA3, sparsevectorA3) ]

RDDB = [ (nameB1, sparsevectorB1), (nameB2, sparsevectorB2) ]

我希望最终结果将第一个 RDD 的每个元素与第二个 RDD 中的每个元素进行比较,生成 3 * 2 = 6 个元素的 RDD。特别是,我想要第二个 RDD 中元素的名称和两个稀疏向量的点积:

RDDC = [ (nameB1, sparsevectorA1.dot(sparsevectorB1)), (nameB2, sparsevectorA1.dot(sparsevectorB2)), 
(nameB1, sparsevectorA2.dot(sparsevectorB1)), (nameB2, sparsevectorA2.dot(sparsevectorB2)), 
(nameB1, sparsevectorA3.dot(sparsevectorB1)), (nameB2, sparsevectorA3.dot(sparsevectorB2)) ]

是否有合适的地图或内置函数来执行此操作?

我认为这样的手术一定存在,因此我有一种无脑的感觉。如果我收集两个 RDD 然后实现一个 for 循环,我可以轻松且不优雅地做到这一点,但当然这并不令人满意,因为我想将它们保持为 RDD 形式。

感谢您的帮助!

【问题讨论】:

    标签: apache-spark pyspark


    【解决方案1】:

    是否有合适的地图或内置函数来执行此操作?

    是的,有,它叫cartesian

    def transform(ab):
        (_, vec_a), (name_b, vec_b) = ab
        return name_b, vec_a.dot(vec_b)
    
    rddA.cartesian(rddB).map(transform)
    

    问题是大型数据集上的笛卡尔积通常是一个非常糟糕的主意,而且通常有更好的方法。

    【讨论】:

    • 太好了,这看起来就像我要求的一样,谢谢!你有一个“更好的方法”的例子吗?我很想看看专业人士是如何解决这些问题的。
    • 没有上下文就很难说。如果您使用稀疏向量,那么好的起点是将问题减少到显式连接,您只比较共享至少一个非零位置的元素。 flatMap -> join -> distinct -> 比较。可以有一些更智能的特定领域解决方案(例如空间分区 + mapPartitions 或修改后的 LSH)。
    猜你喜欢
    • 1970-01-01
    • 2016-08-23
    • 1970-01-01
    • 1970-01-01
    • 2016-12-16
    • 2017-08-10
    • 2017-07-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多