web-dev-qa-db-fra.com

Fractionner des chaînes dans Apache Spark à l'aide de Scala

J'ai un jeu de données qui contient des lignes au format (séparées par des tabulations):

Title<\t>Text

Maintenant, pour chaque mot dans Text, je veux créer une paire (Word,Title). Par exemple:

ABC      Hello World

donne moi

(Hello, ABC)
(World, ABC)

En utilisant Scala, j'ai écrit ce qui suit:

val file = sc.textFile("s3n://file.txt")
val title = file.map(line => line.split("\t")(0))
val wordtitle = file.map(line => (line.split("\t")(1).split(" ").map(Word => (Word, line.split("\t")(0)))))

Mais cela me donne la sortie suivante:

[Lscala.Tuple2;@2204b589
[Lscala.Tuple2;@632a46d1
[Lscala.Tuple2;@6c8f7633
[Lscala.Tuple2;@3e9945f3
[Lscala.Tuple2;@40bf74a0
[Lscala.Tuple2;@5981d595
[Lscala.Tuple2;@5aed571b
[Lscala.Tuple2;@13f1dc40
[Lscala.Tuple2;@6bb2f7fa
[Lscala.Tuple2;@32b67553
[Lscala.Tuple2;@68d0b627
[Lscala.Tuple2;@8493285

Comment résoudre ce problème? 

Lectures complémentaires

Ce que je veux réaliser est de compter le nombre de Words qui se produisent dans un Text pour un Title particulier.

Le code suivant que j'ai écrit est:

val wordcountperfile = file.map(line => (line.split("\t")(1).split(" ").flatMap(Word => Word), line.split("\t")(0))).map(Word => (Word, 1)).reduceByKey(_ + _)

Mais ça ne marche pas. N'hésitez pas à donner votre avis à ce sujet. Merci!

4
AngryPanda

Alors ... Dans spark, vous travaillez en utilisant une structure de données distribuée appelée RDD. Ils fournissent des fonctionnalités similaires aux types de collection scala.

val fileRdd = sc.textFile("s3n://file.txt")
// RDD[ String ]

val splitRdd = fileRdd.map( line => line.split("\t") )
// RDD[ Array[ String ]

val yourRdd = splitRdd.flatMap( arr => {
  val title = arr( 0 )
  val text = arr( 1 )
  val words = text.split( " " )
  words.map( Word => ( Word, title ) )
} )
// RDD[ ( String, String ) ]

// Now, if you want to print this...
yourRdd.foreach( { case ( Word, title ) => println( s"{ $Word, $title }" ) } )

// if you want to count ( this count is for non-unique words), 
val countRdd = yourRdd
  .groupBy( { case ( Word, title ) => title } )  // group by title
  .map( { case ( title, iter ) => ( title, iter.size ) } ) // count for every title
7

Voici comment résoudre ce problème à l’aide de la nouvelle API Dataframe . Commencez par lire les données en utilisant "\ t" comme délimiteur:

val df = spark.read
  .option("delimiter", "\t")
  .option("header", false)
  .csv("s3n://file.txt")
  .toDF("title", "text")

Ensuite, split la colonne text de l'espace et explode pour obtenir un mot par ligne.

val df2 = df.select($"title", explode(split($"text", " ")).as("words"))

Enfin, groupez sur la colonne title et comptez le nombre de mots pour chacun.

val countDf = df2.groupBy($"title").agg(count($"words"))
1
Shaido

Une autre version avec DataFrame API

// read into DataFrame
val viewsDF=spark.read.text("s3n://file.txt")

// Split
val splitedViewsDF = viewsDF.withColumn("col1", split($"value", "\\t").getItem(0)).withColumn("col2", split($"value", "\\s+").getItem(1)).drop($"value"))

Échantillon

scala> val viewsDF=spark.read.text("spark-labs/data/wiki-pageviews.txt")
viewsDF: org.Apache.spark.sql.DataFrame = [value: string]

scala> viewsDF.printSchema
root
 |-- value: string (nullable = true)


scala> viewsDF.limit(5).show
+------------------+
|             value|
+------------------+
|  aa Main_Page 3 0|
|  aa Main_page 1 0|
|  aa User:Savh 1 0|
|  aa Wikipedia 1 0|
|aa.b User:Savh 1 0|
+------------------+


scala> val splitedViewsDF = viewsDF.withColumn("col1", split($"value", "\\s+").getItem(0)).withColumn("col2", split($"value", "\\s+").getItem(1)).withColumn("col3", split($"value", "\\s+").getItem(2)).drop($"value")
splitedViewsDF: org.Apache.spark.sql.DataFrame = [col1: string, col2: string ... 1 more field]

scala>

scala> splitedViewsDF.printSchema
root
 |-- col1: string (nullable = true)
 |-- col2: string (nullable = true)
 |-- col3: string (nullable = true)


scala> splitedViewsDF.limit(5).show
+----+---------+----+
|col1|     col2|col3|
+----+---------+----+
|  aa|Main_Page|   3|
|  aa|Main_page|   1|
|  aa|User:Savh|   1|
|  aa|Wikipedia|   1|
|aa.b|User:Savh|   1|
+----+---------+----+


scala>
0
Zhen Zeng