Spark:Dataframe 管道分隔不返回正确的值

Posted

技术标签:

【中文标题】Spark:Dataframe 管道分隔不返回正确的值【英文标题】:Spark: Dataframe pipe delimited doesn't return correct values 【发布时间】:2019-09-10 06:22:53 【问题描述】:

我的数据框如下:

scala> products_df.show(5)
+--------------------+
|               value|
+--------------------+
|1009|45|Diamond F...|
|1010|46|DBX Vecto...|
|1011|46|Old Town ...|
|1012|46|Pelican T...|
|1013|46|Perceptio...|
+--------------------+

我需要明智地划分每一列-

我使用下面的查询,它适用于所有其他分隔符,但在这里它不起作用 ==>

products_df.selectExpr(("cast((split(value,'|'))[0] as int) as product_id"),("cast((split(value,'|'))[1] as int) as product_category_id"),("cast((split(value,'|'))[2] as string) as product_name"),("cast((split(value,'|'))[3] as string) as description"), ("cast((split(value,'|'))[4] as float) as product_price") ,("cast((split(value,'|'))[5] as string) as product_image")).show

它返回 -

product_id|product_category_id|product_name|description|product_price|product_image|
+----------+-------------------+------------+-----------+-------------+-------------+
|         1|                  0|           0|          9|         null|            4|
|         1|                  0|           1|          0|         null|            4|
|         1|                  0|           1|          1|         null|            4|
|         1|                  0|           1|          2|         null|            4|
|         1|                  0|           1|          3|         null|            4|
|         1|                  0|           1|          4|         null|            4|
|         1|                  0|           1|          5|         null|            4|

文件用逗号(,)或(:)分隔时可以正常工作 仅使用 pipe(|) 并返回上述值,而它应该是

product_id|product_category_id|        product_name|description|product_price|       product_image|
+----------+-------------------+--------------------+-----------+-------------+--------------------+
|      1009|                 45|Quest Q64 10 FT. ...|           |        59.98|http://images.acm...|
|      1010|                 46|Under Armour Men'...|           |       129.99|http://images.acm...|
|      1011|                 47|Under Armour Men'...|           |        89.99|http://images.acm...|

【问题讨论】:

你是如何加载文件的?如果是 csv 则使用使用 option("delimiter", "|") 示例:spark.read.option("delimiter", "|").csv(file) 或 sep 而不是 delimiter。 split(value, "\\|")分割呢? 我正在以所需的管道分隔格式对其进行排序。我尝试使用转义但没有用。 @alam 这个问题在我看来是 selectExpr split for pipe separator only bcoz if you will do withColumn df2.withColumn("t",split($"value","\\|")( 0)).show 它给了我预期的结果。所以你可以尝试使用 withcolumn 。 @ Mahesh - 谢谢它有效 --- 现在看起来如下 val products_df=spark.read.textFile("/user/products").withColumn("product_id",split($"value ","\\|")(0).cast("int")).withColumn("product_cat_id",split($"value","\\|")(1).cast("int")) .withColumn("product_name",split($"value","\\|")(2).cast("string")).withColumn("product_description",split($"value","\\|" )(3).cast("string")).withColumn("product_price",split($"value","\\|")(4).cast("float")).withColumn("product_image", split($"value","\\|")(5).cast("string")).select("product_id","product_cat_id","product_name","product_de......)跨度> 【参考方案1】:

谢谢大家的建议- -> 当文件由管道(|)分隔时,selectExpr 似乎不起作用。 所以另一种方法是使用 withColumn。

val products_df=spark.read.textFile("/user/code/products").withColumn("product_id",split($"value","\|")(0).cast("int") ).withColumn("product_cat_id",split($"value","\|")(1).cast("int")).withColumn("product_name",split($"value","\|") (2).cast("string")).withColumn("product_description",split($"value","\|")(3).cast("string")).withColumn("product_price",split( $"value","\|")(4).cast("float")).withColumn("product_image",split($"value","\|")(5).cast("string") ).select("product_id","product_cat_id","product_name","product_description","product_price","product_image")

【讨论】:

【参考方案2】:

Spark 2.4.3 只需添加整洁干净的代码

scala> var df =Seq(("1009|45|Diamond F"),("1010|46|DBX Vecto")).toDF("value")

scala> df.show
+-----------------+
|            value|
+-----------------+
|1009|45|Diamond F|
|1010|46|DBX Vecto|
+-----------------+
val splitedViewsDF = df.withColumn("product_id", split($"value", "\\|").getItem(0)).withColumn("product_cat_id", split($"value", "\\|").getItem(1)).withColumn("product_name", split($"value", "\\|").getItem(2)).drop($"value")

scala> splitedViewsDF.show
+----------+--------------+------------+
|product_id|product_cat_id|product_name|
+----------+--------------+------------+
|      1009|            45|   Diamond F|
|      1010|            46|   DBX Vecto|
+----------+--------------+------------+

在这里您可以使用 getItem 获取数据。快乐的 Hadoop

【讨论】:

谢谢,Mahesh ...确实更好,尤其是 drop 部分。 欢迎,希望对你有帮助

以上是关于Spark:Dataframe 管道分隔不返回正确的值的主要内容,如果未能解决你的问题,请参考以下文章

Spark2.0 Pipelines

使用 spark.sql parse_url() 从包含大括号或管道的 URL 中提取主机

Dataframe Spark Scala中的最后一个聚合函数

spark dataframe函数编程

林子雨spark scala版编程小结

Spark 'join' DataFrame 与 List 并返回 String