scala - 在 Zeppelin 上的 scala 中使用 Spark 拆分一列并将部分连接成一个新列
问题描述
这是我的数据框的样子:
p3.show(false)
CLASS_NAME ID CREATED_BY
/SC/ABC/123/abc 123 david
/SC/DEF/456/ghi 456 hannah
... more rows to follow
我想做的是:拆分CLASS_NAME
列并连接它的前两个字符串部分并形成一个新列:CLIENT_ID
并附加到数据框,所需的输出如下:
CLASS_NAME ID CREATED_BY CLIENT_ID
/SC/ABC/123/abc xyz david /SC/ABC
/SC/DEF/456/ghi jfk hannah /SC/DEF
... more rows to follow
到目前为止,我能够遵循这个答案并使用以下命令将它们拆分:
import org.apache.spark.sql.functions.split
import spark.implicits._
val p4 = p3.withColumn("CLIENT_ID", split($"CLASS_NAME", "\\/")).select(
$"CLIENT_ID".getItem(1).as("col1"),
$"CLIENT_ID".getItem(2).as("col2"),
$"CLIENT_ID".getItem(3).as("col3")
)
p4.show(false)
col1 col2 col3
SC ABC 123
SC DEF 456
... more rows to follow
但我还没有弄清楚如何 1. 连接两个字符串;2. 将此新列附加到原始数据框中。
任何想法将不胜感激!
解决方案
您可以使用concat组合三个部分中的两个:
import org.apache.spark.sql.functions.concat
import org.apache.spark.sql.functions.lit
val p4 = p3.withColumn("CLIENT_ID", split($"CLASS_NAME", "\\/"))
.withColumn("CLIENT_ID", concat(lit("/"), $"CLIENT_ID".getItem(1), lit("/"), $"CLIENT_ID".getItem(2)))
另一种选择是使用regexp_extract:
import org.apache.spark.sql.functions.regexp_extract
val p4 = p3.withColumn("CLIENT_ID", regexp_extract($"CLASS_NAME", "(/[A-Z]+/[A-Z]+)/", 1))
两种情况的结果:
+---------------+---+----------+---------+
| CLASS_NAME| ID|CREATED_BY|CLIENT_ID|
+---------------+---+----------+---------+
|/SC/ABC/123/abc|123| david| /SC/ABC|
|/SC/DEF/456/ghi|456| hannah| /SC/DEF|
+---------------+---+----------+---------+
推荐阅读
- javascript - 检查对象属性的值和检查属性是否在对象中的区别
- cmake - find_library 如何处理版本号?
- javascript - Event.target.value 返回空字符串或空白
- ruby-on-rails - 在测试环境中禁用伪造保护时,测试如何抛出 InvalidAuthenticityToken?
- angular - Angular 中的 @Input 和 @HostBinding 装饰器有什么区别?
- python - Django:唯一约束失败:user.username
- bitbucket-pipelines - 为什么类星体“构建”不是一个已知命令?
- react-native - 在 Arduino 和 React Native 应用程序之间设置加密密钥
- python - 使用浮点列表进行循环
- sql - 在 Google Big Query 中将两个数组连接在一起