web-dev-qa-db-fra.com

Spark: Convertit une colonne de chaîne en un tableau

Comment convertir une colonne lue sous forme de chaîne en une colonne de tableaux? I.e. convertir à partir du schéma ci-dessous

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

+---+---+
|  a|  b|
+---+---+
|  1|2,3|
+---+---+
|  2|4,5|
+---+---+

À: 

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

+---+-----+
|  a|  b  |
+---+-----+
|  1|[2,3]|
+---+-----+
|  2|[4,5]|
+---+-----+

S'il vous plaît partager les deux implémentation scala et python si possible. Sur une note connexe, comment puis-je m'en occuper lors de la lecture du fichier lui-même? lecture dans pyspark comme ci-dessous:

df = spark.read.format('com.databricks.spark.csv').options(
    header='true', inferschema='true', delimiter='|').load(input_file)

Merci.

6
Nikhil Utane

Il existe différentes méthodes,

La meilleure façon de le faire est d'utiliser la fonction split et de transtyper en array<long>

data.withColumn("b", split(data("b"), ",").cast("array<long>"))

Vous pouvez également créer un fichier UDF simple pour convertir les valeurs. 

val tolong = udf((value : String) => value.split(",").map(_.toLong))

data.withColumn("newB", tolong(data("b"))).show

J'espère que cela t'aides!

7
Shankar Koirala

Utiliser un UDF vous donnerait le schéma exact requis. Comme ça:

val toArray = udf((b: String) => b.split(",").map(_.toLong))

val test1 = test.withColumn("b", toArray(col("b")))

Cela vous donnerait le schéma suivant:

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

+---+-----+
|  a|  b  |
+---+-----+
|  1|[2,3]|
+---+-----+
|  2|[4,5]|
+---+-----+

En ce qui concerne l’application du schéma sur fichier lu, c’est une tâche difficile. Ainsi, pour le moment, vous pouvez appliquer une transformation après avoir créé DataFrameReader sur test.

J'espère que ça aide!

2
himanshuIIITian

En python (pyspark) ce serait: 

from pyspark.sql.types import *
from pyspark.sql.functions import col, split
test = test.withColumn(
        "b",
        split(col("b"), ",\s*").cast("array<int>").alias("ev")
 )
0
Ariana Bermúdez