我正在尝试下面给出的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]]
答案 0 :(得分:1)
无需使用collect
来收集驱动程序节点上的所有数据,您可以在没有它的情况下进行所有转换。我们的想法是过滤长度以删除长度为1的模式,使用init
和last
将数组拆分为两部分,然后转换为toDF
的数据框。代码如下:
val df = model.freqSequences.map(_.sequence)
.filter(_.length > 1)
.map(a => (a.init, Array(a.last)))
.toDF("left", "right")
mkString
只需一个数组并将其转换为一个字符串,其中包含一些关于它应该如何显示的规范,此处[
放在开头,]
放在最后{ {1}}作为分隔符。部分输出如下:
,