web-dev-qa-db-fra.com

Aplatissement des rangées dans l'étincelle

Je suis en train de tester l'étincelle à l'aide de scala. Nous lisons généralement des fichiers json qui doivent être manipulés comme dans l'exemple suivant:

test.json:

{"a":1,"b":[2,3]}
val test = sqlContext.read.json("test.json")

Comment puis-je le convertir au format suivant:

{"a":1,"b":2}
{"a":1,"b":3}
27
Nir Ben Yaacov

Vous pouvez utiliser la fonction explode:

scala> import org.Apache.spark.sql.functions.explode
import org.Apache.spark.sql.functions.explode


scala> val test = sqlContext.read.json(sc.parallelize(Seq("""{"a":1,"b":[2,3]}""")))
test: org.Apache.spark.sql.DataFrame = [a: bigint, b: array<bigint>]

scala> test.printSchema
root
 |-- a: long (nullable = true)
 |-- b: array (nullable = true)
 |    |-- element: long (containsNull = true)

scala> val flattened = test.withColumn("b", explode($"b"))
flattened: org.Apache.spark.sql.DataFrame = [a: bigint, b: bigint]

scala> flattened.printSchema
root
 |-- a: long (nullable = true)
 |-- b: long (nullable = true)

scala> flattened.show
+---+---+
|  a|  b|
+---+---+
|  1|  2|
|  1|  3|
+---+---+
50
zero323

il est souvent suggéré d’exploser, mais cela provient de l’API DataFrame non typée et, étant donné que vous utilisez Dataset, je pense que l’opérateur flatMap pourrait être plus approprié (voir org.Apache.spark.sql.Dataset ).

flatMap[U](func: (T) ⇒ TraversableOnce[U])(implicit arg0: Encoder[U]): Dataset[U]

(Spécifique à Scala) Retourne un nouveau jeu de données en appliquant d'abord une fonction à tous les éléments de ce jeu de données, puis en aplatissant les résultats.

Vous pouvez l'utiliser comme suit:

val ds = Seq(
  (0, "Lorem ipsum dolor", 1.0, Array("prp1", "prp2", "prp3")))
  .toDF("id", "text", "value", "properties")
  .as[(Integer, String, Double, scala.List[String])]

scala> ds.flatMap { t => 
  t._4.map { prp => 
    (t._1, t._2, t._3, prp) }}.show
+---+-----------------+---+----+
| _1|               _2| _3|  _4|
+---+-----------------+---+----+
|  0|Lorem ipsum dolor|1.0|prp1|
|  0|Lorem ipsum dolor|1.0|prp2|
|  0|Lorem ipsum dolor|1.0|prp3|
+---+-----------------+---+----+

// or just using for-comprehension
for {
  t <- ds
  prp <- t._4
} yield (t._1, t._2, t._3, prp)
0
Anurag Sharma