Нужно сгладить массив данных на основе одного столбца в Scala - PullRequest
0 голосов
/ 10 июля 2019

У меня есть фрейм данных со схемой ниже

 root
 |-- name: string (nullable = true)
 |-- roll: string (nullable = true)
 |-- subjectID: string (nullable = true)

Значения в фрейме данных такие, как показано ниже

+-------------------+---------+--------------------+
|               name|     roll|           SubjectID|
+-------------------+---------+--------------------+
|                sam|ta1i3dfk4|            xy|av|mm|
|               royc|rfhqdbnb3|                   a|
|             alcaly|ta1i3dfk4|               xx|zz|
+-------------------+---------+--------------------+

Мне нужно вывести фрейм данных по идентификатору субъекта flattenig, как показано ниже.обратите внимание: SubjectID также является строкой

+-------------------+---------+--------------------+
|               name|     roll|           SubjectID|
+-------------------+---------+--------------------+
|                sam|ta1i3dfk4|                  xy|
|                sam|ta1i3dfk4|                  av|
|                sam|ta1i3dfk4|                  mm|
|               royc|rfhqdbnb3|                   a|
|             alcaly|ta1i3dfk4|                  xx|
|             alcaly|ta1i3dfk4|                  zz|
+-------------------+---------+--------------------+

Любое предложение

Ответы [ 2 ]

2 голосов
/ 10 июля 2019

Вы можете использовать explode функции для выравнивания. Пример:

 val inputDF = Seq(
      ("sam", "ta1i3dfk4", "xy|av|mm"),
      ("royc", "rfhqdbnb3", "a"),
      ("alcaly", "rfhqdbnb3", "xx|zz")
    ).toDF("name", "roll", "subjectIDs")

  //split and explode `subjectIDs`
val result = input.withColumn("subjectIDs",
  split(col("subjectIDs"), "\\|"))
  .withColumn("subjectIDs", explode($"subjectIDs"))

    resultDF.show()

    +------+---------+----------+ 
    |  name|     roll|subjectIDs|
    +------+---------+----------+
    |   sam|ta1i3dfk4|        xy|
    |   sam|ta1i3dfk4|        av|
    |   sam|ta1i3dfk4|        mm|
    |  royc|rfhqdbnb3|         a|
    |alcaly|rfhqdbnb3|        xx|
    |alcaly|rfhqdbnb3|        zz|
    +------+---------+----------+
1 голос
/ 10 июля 2019

Вы можете использовать flatMap в наборе данных.Полный исполняемый код:

package main

import org.apache.spark.sql.{Dataset, SparkSession}

object Main extends App {
  case class Roll(name: Option[String], roll: Option[String], subjectID: Option[String])

  val mySpark = SparkSession
    .builder()
    .master("local[2]")
    .appName("Spark SQL basic example")
    .getOrCreate()
  import mySpark.implicits._

  val inputDF: Dataset[Roll] = Seq(
    ("sam", "ta1i3dfk4", "xy|av|mm"),
    ("royc", "rfhqdbnb3", "a"),
    ("alcaly", "rfhqdbnb3", "xx|zz")
  ).toDF("name", "roll", "subjectID").as[Roll]

  val out: Dataset[Roll] = inputDF.flatMap {
    case Roll(n, r, Some(ids)) if ids.nonEmpty =>
      ids.split("\\|").map(id => Roll(n, r, Some(id)))
    case x => Some(x)
  }
  out.show()
}

Примечание:

  1. вы можете использовать split('|') вместо split("\\|")
  2. вы можете изменить дескриптор по умолчанию, если идентификатор должен бытьне пустой
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...