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.
Dans Spark 2.1+ pour concaténer les valeurs d'une seule colonne de tableau, vous pouvez utiliser les éléments suivants:
concat_ws
fonction standardmap
opérateurUtilisez 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|
+--------------+-----------+
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)
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)))
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.