web-dev-qa-db-fra.com

Comment utiliser un ensemble de données pour groupby

J'ai une demande d'utilisation de rdd pour le faire :

val test = Seq(("New York", "Jack"),
    ("Los Angeles", "Tom"),
    ("Chicago", "David"),
    ("Houston", "John"),
    ("Detroit", "Michael"),
    ("Chicago", "Andrew"),
    ("Detroit", "Peter"),
    ("Detroit", "George")
  )
sc.parallelize(test).groupByKey().mapValues(_.toList).foreach(println)

Le résultat est que:

(New York, Liste (Jack))

(Detroit, List (Michael, Peter, George))

(Los Angeles, List (Tom))

(Houston, List (John))

(Chicago, List (David, Andrew))

Comment faire pour utiliser un jeu de données avec spark2.0?

J'ai un moyen d'utiliser une fonction personnalisée, mais le sentiment est tellement compliqué qu'il n'y a pas de méthode de point simple

3
monkeysjourney

Je vous suggère de commencer par créer un case class comme

case class Monkey(city: String, firstName: String)

Ce case class doit être défini en dehors de la classe principale. Ensuite, vous pouvez simplement utiliser la fonction toDS et utiliser les fonctions groupBy et aggregation appelées collect_list comme ci-dessous

import sqlContext.implicits._
import org.Apache.spark.sql.functions._

val test = Seq(("New York", "Jack"),
  ("Los Angeles", "Tom"),
  ("Chicago", "David"),
  ("Houston", "John"),
  ("Detroit", "Michael"),
  ("Chicago", "Andrew"),
  ("Detroit", "Peter"),
  ("Detroit", "George")
)
sc.parallelize(test).map(row => Monkey(row._1, row._2)).toDS().groupBy("city").agg(collect_list("firstName") as "list").show(false)

Vous aurez la sortie comme 

+-----------+------------------------+
|city       |list                    |
+-----------+------------------------+
|Los Angeles|[Tom]                   |
|Detroit    |[Michael, Peter, George]|
|Chicago    |[David, Andrew]         |
|Houston    |[John]                  |
|New York   |[Jack]                  |
+-----------+------------------------+

Vous pouvez toujours reconvertir en RDD en appelant simplement la fonction .rdd

4
Ramesh Maharjan

Pour créer un jeu de données, définissez d’abord une classe de cas en dehors de votre classe en tant que 

case class Employee(city: String, name: String)

Ensuite, vous pouvez convertir la liste en jeu de données en tant que 

  val spark =
    SparkSession.builder().master("local").appName("test").getOrCreate()
    import spark.implicits._
    val test = Seq(("New York", "Jack"),
    ("Los Angeles", "Tom"),
    ("Chicago", "David"),
    ("Houston", "John"),
    ("Detroit", "Michael"),
    ("Chicago", "Andrew"),
    ("Detroit", "Peter"),
    ("Detroit", "George")
    ).toDF("city", "name")
    val data = test.as[Employee]

Ou 

    import spark.implicits._
    val test = Seq(("New York", "Jack"),
      ("Los Angeles", "Tom"),
      ("Chicago", "David"),
      ("Houston", "John"),
      ("Detroit", "Michael"),
      ("Chicago", "Andrew"),
      ("Detroit", "Peter"),
      ("Detroit", "George")
    )

    val data = test.map(r => Employee(r._1, r._2)).toDS()

Maintenant, vous pouvez groupby et effectuer toute agrégation de la manière suivante:

data.groupBy("city").count().show

data.groupBy("city").agg(collect_list("name")).show

J'espère que cela t'aides!

1
Shankar Koirala

Premièrement, je transformerais votre RDD en un DataSet:

val spark: org.Apache.spark.sql.SparkSession = ???
import spark.implicits._

val testDs = test.toDS()

Ici, vous obtenez vos noms de col :) Utilisez-le sagement!

testDs.schema.fields.foreach(x => println(x))

En fin de compte, vous devez uniquement utiliser un groupePar:

testDs.groupBy("City?", "Name?")

Les RDD-s ne sont pas vraiment la version 2.0, je pense. Si vous avez des questions, posez-les simplement.

0
András Nagy