Spark Scala使用case when对group列分类不生效,如何高效实现需求?
问题原因分析
- 你代码中的
col("group").match属于错误写法:Spark的Column类没有match属性,该写法本身会触发语法错误,即便你想调用匹配相关API也用错了调用方式。 - 缺少「提取
gr=后三位字母」的前置步骤:你代码中的when判断是直接和完整的group列值做相等匹配,而group列存储的是gr=xxx, xxx格式的完整字符串,不可能和nat/pjc这类短字符串匹配成功,所有判断都会走到otherwise分支返回Unknown。
最高效实现方案
直接使用Spark内置的regexp_extract函数做正则提取即可,内置函数是向量化执行的,性能远高于自定义UDF,不会产生额外的序列化开销。
正确实现代码如下:
import org.apache.spark.sql.functions._ val df2 = df // 第一步提取gr=后面的3位编码,存入临时列gr_code .withColumn("gr_code", regexp_extract(col("group"), "gr=([a-z0-9]{3})", 1)) .withColumn("tgroup", when(col("gr_code") === "nat", "nat_1_nm") .when(col("gr_code") === "pjc", "pjc_determined") .when(col("gr_code") === "ntp", "ntp_dway") .otherwise("Unknown") ) // 如果不需要保留中间的gr_code列可以放开下面的注释 //.drop("gr_code")
上述代码中正则gr=([a-z0-9]{3})的逻辑是匹配gr=开头后紧跟的3位字母/数字字符,提取分组1的内容就是你需要的三位编码。
如果想要一步完成不需要中间列,也可以直接把提取逻辑写入when的判断条件:
import org.apache.spark.sql.functions._ val df2 = df.withColumn("tgroup", when(regexp_extract(col("group"), "gr=([a-z0-9]{3})", 1) === "nat", "nat_1_nm") .when(regexp_extract(col("group"), "gr=([a-z0-9]{3})", 1) === "pjc", "pjc_determined") .when(regexp_extract(col("group"), "gr=([a-z0-9]{3})", 1) === "ntp", "ntp_dway") .otherwise("Unknown") )
更推荐第一种写法,逻辑更清晰,也避免了重复计算正则提取逻辑。
内容的提问来源于stack exchange,提问作者CloudSparkie
相关产品推荐
相关产品推荐

