[英]How do you split a column such that first half becomes the column name and the second the column value in Scala Spark?
[英]How do I split a column by using delimiters from another column in Spark/Scala
我有另一个与拆分 function 相关的问题。我是 Spark/Scala 的新手。
以下是示例数据框 -
+-------------------+---------+
| VALUES|Delimiter|
+-------------------+---------+
| 50000.0#0#0#| #|
| 0@1000.0@| @|
| 1$| $|
|1000.00^Test_string| ^|
+-------------------+---------+
我希望 output 成为 -
+-------------------+---------+----------------------+
|VALUES |Delimiter|split_values |
+-------------------+---------+----------------------+
|50000.0#0#0# |# |[50000.0, 0, 0, ] |
|0@1000.0@ |@ |[0, 1000.0, ] |
|1$ |$ |[1, ] |
|1000.00^Test_string|^ |[1000.00, Test_string]|
+-------------------+---------+----------------------+
我试图手动拆分 -
dept.select(split(col("VALUES"),"#|@|\\$|\\^").show()
而 output 是 -
+-----------------------+
|split(VALUES,#|@|\$|\^)|
+-----------------------+
| [50000.0, 0, 0, ]|
| [0, 1000.0, ]|
| [1, ]|
| [1000.00, Test_st...|
+-----------------------+
但我想为大型数据集自动拉起分隔符。
您需要将expr
与split()
一起使用以使拆分动态
df = spark.createDataFrame([("50000.0#0#0#","#"),("0@1000.0@","@")],["VALUES","Delimiter"])
df = df.withColumn("split", F.expr("""split(VALUES, Delimiter)"""))
df.show()
+------------+---------+-----------------+
| VALUES|Delimiter| split|
+------------+---------+-----------------+
|50000.0#0#0#| #|[50000.0, 0, 0, ]|
| 0@1000.0@| @| [0, 1000.0, ]|
+------------+---------+-----------------+
编辑:请检查 Scala 版本的答案底部。
您可以使用自定义用户定义函数 ( pyspark.sql.functions.udf
) 来实现此目的。
from typing import List
from pyspark.sql import SparkSession
from pyspark.sql.functions import udf
from pyspark.sql.types import StringType, ArrayType
def split_col(value: StringType, delimiter: StringType) -> List[str]:
return str(value).split(str(delimiter))
udf_split = udf(lambda x, y: split_col(x, y), ArrayType(StringType()))
spark = SparkSession.builder.getOrCreate()
df = spark.createDataFrame([
('50000.0#0#0#', '#'), ('0@1000.0@', '@'), ('1$', '$'), ('1000.00^Test_string', '^')
], schema='VALUES String, Delimiter String')
df = df.withColumn("split_values", udf_split(df['VALUES'], df['Delimiter']))
df.show(truncate=False)
输出
+-------------------+---------+----------------------+
|VALUES |Delimiter|split_values |
+-------------------+---------+----------------------+
|50000.0#0#0# |# |[50000.0, 0, 0, ] |
|0@1000.0@ |@ |[0, 1000.0, ] |
|1$ |$ |[1, ] |
|1000.00^Test_string|^ |[1000.00, Test_string]|
+-------------------+---------+----------------------+
请注意, split_values
列包含一个字符串列表。 您还可以更新split_col
函数以对值进行更多更改。
编辑: Scala 版本
import org.apache.spark.sql.functions.udf
import spark.implicits._
val data = Seq(("50000.0#0#0#", "#"), ("0@1000.0@", "@"), ("1$", "$"), ("1000.00^Test_string", "^"))
var df = data.toDF("VALUES", "Delimiter")
val udf_split_col = udf {(x:String,y:String)=> x.split(y)}
df = df.withColumn("split_values", udf_split_col(df.col("VALUES"), df.col("Delimiter")))
df.show(false)
编辑 2
为了避免在正则表达式中使用特殊字符的问题,您可以在使用split()
方法时使用 char 而不是 String ,如下所示。
val udf_split_col = udf { (x: String, y: String) => x.split(y.charAt(0)) }
这是另一种处理方式,使用 sparksql
df.createOrReplaceTempView("test")
spark.sql("""select VALUES,delimiter,split(values,case when delimiter in ("$","^") then concat("\\",delimiter) else delimiter end) as split_value from test""").show(false)
请注意,我包含 case when 语句以添加转义字符来处理 '$' 和 '^' 的情况,否则它不会拆分。
+-------------------+---------+----------------------+
|VALUES |delimiter|split_value |
+-------------------+---------+----------------------+
|50000.0#0#0# |# |[50000.0, 0, 0, ] |
|0@1000.0@ |@ |[0, 1000.0, ] |
|1$ |$ |[1, ] |
|1000.00^Test_string|^ |[1000.00, Test_string]|
+-------------------+---------+----------------------+
这是我最近的解决方案
import java.util.regex.Pattern
val split_udf = udf((value: String, delimiter: String) => value.split(Pattern.quote(delimiter), -1))
val solution = dept.withColumn("split_values", split_udf(col("VALUES"),col("Delimiter")))
solution.show(truncate = false)
它将跳过分隔符列中的特殊字符。 其他答案不适用于
("50000.0\\0\\0\\", "\\")
而linusRian的回答需要手动添加特殊字符
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.