在 PrefixSpan 之后拆分数据框

Split a dataframe after PrefixSpan

我正在尝试下面给出的 prefixSpan 算法示例:

import org.apache.spark.mllib.fpm.PrefixSpan

val sequences = sc.parallelize(Seq(
 Array(Array(1, 2), Array(3)),
 Array(Array(1), Array(3, 2), Array(1, 2)),
 Array(Array(1, 2), Array(5)),
 Array(Array(6))
), 2).cache()

val prefixSpan = new PrefixSpan()
 .setMinSupport(0.5)
 .setMaxPatternLength(5)

val model = prefixSpan.run(sequences)
model.freqSequences.collect().foreach { freqSequence =>
  println(
    freqSequence.sequence.map(_.mkString("[", ", ", "]")).mkString("[", ", ", "]") +
    ", " + freqSequence.freq
  )
}

首先,我不理解 .mkString("[", ", ", "]")).mkString("[", ", ", "]" 这部分,因为我是 Scala 的新手。我喜欢 python。我相信它就像 lambda 函数。

输出类似于以下内容:

[[2]], 3
[[5]], 1
[[3]], 2
[[6]], 1
[[1]], 3
...
...
[[1], [2, 3], [2]], 1
[[1], [2, 3], [2, 1]], 1
[[1], [2, 3], [1]], 1

我需要创建一个新的数据框,如果行长度大于 1,例如下面是保留一行:

[[1], [2, 3], [2, 1]], 1

我需要创建一个包含以下内容的新数据框。 right 列始终是数组 ([:-1]) 的最后一个元素,其余部分在 left:

left        |right
------------------------
[[1], [2, 3]]   | [[2, 1]]

无需使用collect收集驱动节点上的所有数据,无需它即可进行所有转换。这个想法是过滤长度以删除长度为 1 的模式,使用 initlast 将数组分成两部分,然后使用 toDF 转换为数据帧。代码如下:

val df = model.freqSequences.map(_.sequence)
  .filter(_.length > 1)
  .map(a => (a.init, Array(a.last)))
  .toDF("left", "right")

mkString 简单地获取一个数组并将其转换为一个字符串,其中包含一些关于它应该如何显示的规范,这里 [ 放在开头, ] 放在最后以 , 作为分隔符。部分输出如下所示:

+-------------+--------+
|         left|   right|
+-------------+--------+
|[[1], [2, 3]]|[[2, 1]]|
|[[1], [2, 3]]|   [[1]]|
|        [[1]]|[[2, 1]]|
|   [[1], [2]]|   [[2]]|
+-------------+--------+