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 管道分隔不返回正确的值的主要内容,如果未能解决你的问题,请参考以下文章
使用 spark.sql parse_url() 从包含大括号或管道的 URL 中提取主机