web-dev-qa-db-fra.com

Comment convertir une colonne de tableaux de chaînes en chaînes?

J'ai une colonne qui est de type array < string > dans les tables d'allumage. J'utilise SQL pour interroger ces tables d'allumage. Je voulais convertir le array < string > en string.

Lorsqu'elle est utilisée, la syntaxe ci-dessous:

select cast(rate_plan_code  as string) as new_rate_plan  from
customer_activity_searches group by rate_plan_code

La colonne rate_plan_code a les valeurs suivantes:

["AAA","RACK","SMOBIX","SMOBPX"] 
["LPCT","RACK"]
["LFTIN","RACK","SMOBIX","SMOBPX"]
["LTGD","RACK"] 
["RACK","LEARLI","NHDP","LADV","LADV2"]

les éléments suivants sont renseignés dans la colonne new_rate_plan:

org.Apache.spark.sql.catalyst.expressions.UnsafeArrayData@e4273d9f
org.Apache.spark.sql.catalyst.expressions.UnsafeArrayData@c1ade2ff
org.Apache.spark.sql.catalyst.expressions.UnsafeArrayData@4f378397
org.Apache.spark.sql.catalyst.expressions.UnsafeArrayData@d1c81377
org.Apache.spark.sql.catalyst.expressions.UnsafeArrayData@552f3317

Les acteurs semblent fonctionner lorsque je convertis decimal en int ou int en double, mais pas dans ce cas. Curieux de savoir pourquoi la distribution ne fonctionne pas ici. J'apprécie grandement votre aide.

9
Teja

Dans Spark 2.1+ pour concaténer les valeurs d'une seule colonne de tableau, vous pouvez utiliser les éléments suivants:

  1. concat_ws fonction standard
  2. map opérateur
  3. une fonction définie par l'utilisateur (UDF)

concat_ws Fonction standard

Utilisez concat_ws function.

concat_ws (sep: String, exprs: Column *): Column Concatène plusieurs colonnes de chaîne d'entrée en une seule colonne de chaîne, à l'aide du séparateur donné.

val solution = words.withColumn("codes", concat_ws(" ", $"rate_plan_code"))
scala> solution.show
+--------------+-----------+
|         words|      codes|
+--------------+-----------+
|[hello, world]|hello world|
+--------------+-----------+

opérateur de carte

Utilisez map operator pour avoir le plein contrôle de ce qui et comment devrait être transformé.

map [U] (func: (T) ⇒ U): Jeu de données [U] Retourne un nouveau jeu de données contenant le résultat de l'application de func à chaque élément.

scala> codes.show(false)
+---+---------------------------+
|id |rate_plan_code             |
+---+---------------------------+
|0  |[AAA, RACK, SMOBIX, SMOBPX]|
+---+---------------------------+

val codesAsSingleString = codes.as[(Long, Array[String])]
  .map { case (id, codes) => (id, codes.mkString(", ")) }
  .toDF("id", "codes")

scala> codesAsSingleString.show(false)
+---+-------------------------+
|id |codes                    |
+---+-------------------------+
|0  |AAA, RACK, SMOBIX, SMOBPX|
+---+-------------------------+

scala> codesAsSingleString.printSchema
root
 |-- id: long (nullable = false)
 |-- codes: string (nullable = true)
15
Jacek Laskowski

Vous pouvez convertir un tableau en chaîne en créer ce df pas en sortie

newdf = df.groupBy('aaa')
  .agg(F.collect_list('bbb').("string").alias('ccc'))

outputdf = newdf.select(
  F.concat_ws(', ' , newdf.aaa, F.format_string('xxxxx(%s)', newdf.ccc)))
1
guohui.li

Dans spark 2.1+, vous pouvez directement utiliser concat_ws pour convertir (concat avec séparateur) chaîne/tableau <String> en chaîne.

select concat_ws(',',rate_plan_code) as new_rate_plan  from
customer_activity_searches group by rate_plan_code

Cela vous donnera une réponse comme:

AAA,RACK,SMOBIX,SMOBPX 
LPCT,RACK
LFTIN,RACK,SMOBIX,SMOBPX
LTGD,RACK 
RACK,LEARLI,NHDP,LADV,LADV2

PS: concat_ws ne fonctionne pas avec le tableau <Long> ..., pour lequel UDF ou map serait la seule option comme le dit Jacek.

1
varun r