【问题标题】:Spark with Scala: compute a table by executing function on each possible pairSpark with Scala:通过在每个可能的对上执行函数来计算表
【发布时间】:2020-11-04 12:33:19
【问题描述】:

我对 Scala/Spark 完全陌生,我正在尝试从头开始创建一个 Spark 应用程序,该应用程序计算 n 整数集之间的确切 Jaccard similarity(您不需要知道它是什么来回答这个问题问题)。

我有一个数据框,其中每一行都是一组整数,例如:

var sets = List(Set(1, 5, 7, 4), Set(3, 5, 0), Set(10, 1, 5)).toDF

还有一个函数jacsim(s1, s2),它返回两个集合之间的 Jaccard 相似度。我想定义一个函数,给定sets 数据帧返回另一个数据帧,该数据帧在位置 (i, j) 处包含jacsim(sets(i), sets(j)) 的结果。我该怎么做?

另外:将生成的数据框用作表格是个好主意吗?我正在阅读 Spark 不“喜欢”被索引访问的行,因为这会阻碍并行性。我应该返回一个包含单行的数据框并将每个可能的对作为新列吗?

【问题讨论】:

    标签: scala apache-spark apache-spark-sql mapreduce


    【解决方案1】:

    正如您提到的,不允许使用索引访问 spark 数据帧。 这是使用 scala spark 数据框的一种解决方案:

    var sets = List(Set(1, 5, 7, 4), Set(3, 5, 0), Set(10, 1, 5)).toDF("sets")
        .withColumn("i",monotonically_increasing_id()) // to create indexes
    
    
    val jaccardSimUDF = udf((set1: Seq[Int], set2: Seq[Int]) => set1.sum +  set2.sum) // dummy function, replace it with your implementation of Jaccard similarity
    
    val resDF = sets.crossJoin(sets.withColumnRenamed("sets", "sets2").withColumnRenamed("i", "j"))
                    .withColumn("jaccardSim", jaccardSimUDF($"sets", $"sets2"))
    

    基本上,我们需要将您的数据框与自身进行交叉连接以拥有所有组合。然后我们可以应用“用户定义函数”(UDF)来计算 jaccard 相似度。请注意,我创建索引是为了方便。

    现在,如果您真的想要拥有一个矩阵,则需要重塑此数据框,但这不是 spark 本质。

    正如评论中指出的 jaccard 相似度函数是对称的 所以你可以过滤不必要的索引,像这样:

    val resDF = sets.crossJoin(sets.withColumnRenamed("sets", "sets2").withColumnRenamed("i", "j"))
                .filter($"i" < $"j")
                .withColumn("jaccardSim", jaccardSimUDF($"sets", $"sets2"))
    

    它可能看起来很难看,因为它仍然涉及完整的交叉连接,但由于 spark 依赖于惰性计算和 Catalyst 优化器,因此在实践中它并不是真正的完整交叉连接。所以我认为没有更好的解决方案。

    【讨论】:

    • 如果操作 jaccardSimUDF 是对称的(如示例中所示)。有没有办法防止 crossJoin 重复索引对(例如 i:1、j:3 = i:3、j:1)?
    • 没错!感谢您的评论。我编辑了答案以在对称函数的情况下显示更好的解决方案。
    猜你喜欢
    • 2011-03-01
    • 1970-01-01
    • 2023-03-15
    • 2018-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-28
    相关资源
    最近更新 更多