在前缀跨度之后拆分数据帧



我正在尝试下面给出的前缀Span算法示例:

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 的新手。我喜欢蟒蛇。我相信它就像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]]|
+-------------+--------+

最新更新