在PrefixSpan之后拆分数据帧

时间:2018-06-19 07:22:01

标签: scala apache-spark apache-spark-sql data-mining apache-spark-mllib

我正在尝试下面给出的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]]

1 个答案:

答案 0 :(得分: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只需一个数组并将其转换为一个字符串,其中包含一些关于它应该如何显示的规范,此处[放在开头,]放在最后{ {1}}作为分隔符。部分输出如下:

,