繁体   English   中英

如何使用Spark将文本文件拆分为多列

[英]How to split a text file into multiple columns with Spark

我在用分隔符“ |”分割文本数据文件时遇到困难 放入数据框列。 我加载的数据文件如下所示:

results1.show()

+--------------------+
|                 all|
+--------------------+
|DEPT_NO|ART_GRP_N...|
|29|102|354814|SKO...|
|29|102|342677|SKO...|
|29|102|334634|DUR...|
|29|102|319337|SKO...|
|29|102|316731|DUR...|
|29|102|316728|DUR...|
|29|102|316702|DUR...|
|29|102|316702|DUR...|
|29|102|276728|I-P...|

我已经尝试了以下2种方法,这些方法在以前的文章中找到:

results1.select(expr("(split(all, '|'))[1]").cast("integer").as("DEPT_NO"),expr("(split(all, '|'))[4]").cast("integer").as("ART_GRP_NO"), expr("(split(all, '|'))[8]").cast("string").as("ART_NO")).show


+-------+----------+------+
|DEPT_NO|ART_GRP_NO|ART_NO|
+-------+----------+------+
|   null|      null|     ||
|      2|         1|     3|
|      2|         1|     3|
|      2|         1|     3|
|      2|         1|     3|
|      2|         1|     3|
|      2|         1|     3|
|      2|         1|     3|
|      2|         1|     3|
|      2|         1|     2|

val dataframe10= sc.textFile(("D:/data/dnr10.txt")
             .toString())
             .map(_.split("|"))
             .map(c => {(c(1), c(2),c(3),c(4))})
             .toDF()
             .show()                 

+---+---+---+---+
| _1| _2| _3| _4|
+---+---+---+---+
|  D|  E|  P|  T|
|  2|  9|  ||  1|
|  2|  9|  ||  1|
|  2|  9|  ||  1|
|  2|  9|  ||  1|
|  2|  9|  ||  1|
|  2|  9|  ||  1|
|  2|  9|  ||  1|
|  2|  9|  ||  1|
|  2|  9|  ||  1|
|  2|  7|  ||  4|

似乎无法识别定界符,因为分割是在每个字符之后而不是在每个“ |”之后完成的。 在这种情况下,有人可以给我提示如何进行正确的分割吗?

使用RDD API :您的错误是String.split需要一个正则表达式 ,其中pipe( "|" )是一个特殊字符,表示“ OR”,因此会拆分任何内容 加-将数组转换为元组时,应从索引0开始

解决方法很简单-转义该字符:

 sc.textFile("D:/data/dnr10.txt")
  .map(_.split("\\|"))
  .map(c => (c(0),c(1),c(2),c(3)))
  .toDF()

使用Dataframe API :与转义管道相同的问题在此适用。 另外,您可以通过拆分一次并在选择列时多次使用该拆分列来简化代码:

import org.apache.spark.sql.functions._
import org.apache.spark.sql.types.IntegerType

results1.withColumn("split", split($"all", "\\|")).select(
  $"split" getItem 0 cast IntegerType as "DEPT_NO",
  $"split" getItem 3 cast IntegerType as "ART_GRP_NO",
  $"split" getItem 7 as "ART_NO"
)

使用Spark 2.0内置的CSV支持 :如果您使用的是Spark 2.0+,则可以让框架为您完成所有艰苦的工作-使用格式“ csv”并将分隔符设置为竖线字符:

val result = sqlContext.read
  .option("header", "true")
  .option("delimiter", "|")
  .option("inferSchema", "true")
  .format("csv")
  .load("D:/data/dnr10.txt")

result.show()
// +-------+----------+------+---+
// |DEPT_NO|ART_GRP_NO|ART_NO| TT|
// +-------+----------+------+---+
// |     29|       102|354814|SKO|
// |     29|       102|342677|SKO|
// |     29|       102|334634|DUR|
// |     29|       102|276728|I-P|
// +-------+----------+------+---+

result.printSchema()
// root
//  |-- DEPT_NO: integer (nullable = true)
//  |-- ART_GRP_NO: integer (nullable = true)
//  |-- ART_NO: integer (nullable = true)
//  |-- TT: string (nullable = true)

您将获得列名,正确的类型-一切... :)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM