如何将字符串数组的列转换为字符串?

Tej*_*ja 12 apache-spark apache-spark-sql

我有一个列,它是array < string >火花表中的类型.我正在使用SQL来查询这些火花表.我想转换array < string >string.

使用以下语法时:

select cast(rate_plan_code  as string) as new_rate_plan  from
customer_activity_searches group by rate_plan_code
Run Code Online (Sandbox Code Playgroud)

rate_plan_code 列具有以下值:

["AAA","RACK","SMOBIX","SMOBPX"] 
["LPCT","RACK"]
["LFTIN","RACK","SMOBIX","SMOBPX"]
["LTGD","RACK"] 
["RACK","LEARLI","NHDP","LADV","LADV2"]
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

演员似乎当我转换工作decimalintintdouble,但不是在这种情况下.好奇为什么演员不在这里工作.非常感谢您的帮助.

Jac*_*ski 19

在Spark 2.1+中,要在单个Array列中进行值的串联,可以使用以下命令:

  1. concat_ws 标准功能
  2. map 操作者
  3. 用户定义的函数(UDF)

concat_ws标准函数

使用concat_ws函数.

concat_ws(sep:String,exprs:Column*):列使用给定的分隔符将多个输入字符串列连接到一个字符串列中.

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

地图运营商

使用map运算符可以完全控制应该转换的内容和方式.

map [U](func:(T)⇒U):Dataset [U]返回一个新的数据集,其中包含将func应用于每个元素的结果.

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)
Run Code Online (Sandbox Code Playgroud)


var*_*n r 7

在 spark 2.1+ 中,您可以直接使用 concat_ws 将 (concat with seperator) string/array< String > 转换为 String 。

select concat_ws(',',rate_plan_code) as new_rate_plan  from
customer_activity_searches group by rate_plan_code
Run Code Online (Sandbox Code Playgroud)

这会给你这样的回应:

AAA,RACK,SMOBIX,SMOBPX 
LPCT,RACK
LFTIN,RACK,SMOBIX,SMOBPX
LTGD,RACK 
RACK,LEARLI,NHDP,LADV,LADV2
Run Code Online (Sandbox Code Playgroud)

PS:concat_ws 不适用于像 array< Long > ...,对于其中 UDF 或 map 将是 Jacek 所说的唯一选项。