【问题标题】:Split a dataframe after PrefixSpan在 PrefixSpan 之后拆分数据帧
【发布时间】:2018-11-28 01:56:43
【问题描述】:

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

【问题讨论】:

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


    【解决方案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]]|
    +-------------+--------+
    

    【讨论】:

    • 但是这里的类型会改变对吧?我们可以保持左右为 :[Array[Array[Int]]] 类型吗?
    • @user2805885:是的,这是可能的。我更改了答案以将两列的类型都保留为 Array[Array[Int]]。将右列设置为仅Array[Int] 似乎更自然(为此只需删除map 中的Array()
    • 你能帮我把model.freqSequences改成与上面类似的数据框吗?我期望的两列是 [Array[Array[Int]]] 与上面相同,另一列是整数(频率)。我需要查看上面的数据框
    • @user2805885:不要只保留第一个map中的序列,而是保留一个元组+频率。然后仅对序列执行其他转换。在toDF 中,只需添加另一列。如果您需要更多详细信息,也许您可​​以在此处的评论中创建一个新问题并链接到它,我很乐意提供帮助。
    猜你喜欢
    • 2015-05-16
    • 2022-12-15
    • 2013-11-16
    相关资源
    最近更新 更多