Spark - 以编程方式创建具有不同数据类型的模式

AJm*_*AJm 3 scala apache-spark apache-spark-sql spark-dataframe

我有一个由 7-8 个字段组成的数据集,这些字段的类型为 String、Int 和 Float。

我正在尝试使用以下方法通过编程方法创建架构:

val schema = StructType(header.split(",").map(column => StructField(column, StringType, true)))
Run Code Online (Sandbox Code Playgroud)

然后将其映射到 Row 类型,如:

val dataRdd = datafile.filter(x => x!=header).map(x => x.split(",")).map(col => Row(col(0).trim, col(1).toInt, col(2).toFloat, col(3), col(4) ,col(5), col(6), col(7), col(8)))
Run Code Online (Sandbox Code Playgroud)

但是在我使用 DF.show() 创建 DataFrame 之后,它给出了 Integer 字段的错误。

那么如何在数据集中有多种数据类型的情况下创建这样的模式

elg*_*oto 5

您在代码中遇到的问题是您将所有字段分配为 StringType。

假设在标题中您只有字段的名称,那么您无法猜测类型。

让我们假设标题字符串是这样的

val header = "field1:Int,field2:Double,field3:String"
Run Code Online (Sandbox Code Playgroud)

那么代码应该是

def inferType(field: String) = field.split(":")(1) match {
   case "Int" => IntegerType
   case "Double" => DoubleType
   case "String" => StringType
   case _ => StringType
}

val schema = StructType(header.split(",").map(column => StructField(column, inferType(column), true)))
Run Code Online (Sandbox Code Playgroud)

对于标题字符串示例,您将获得

root
 |-- field1:Int: integer (nullable = true)
 |-- field2:Double: double (nullable = true)
 |-- field3:String: string (nullable = true)
Run Code Online (Sandbox Code Playgroud)

另一方面。如果您需要的是来自文本的数据框,我建议您直接从文件本身创建数据框。从 RDD 创建它是没有意义的。

val fileReader = spark.read.format("com.databricks.spark.csv")
  .option("mode", "DROPMALFORMED")
  .option("header", "true")
  .option("inferschema", "true")
  .option("delimiter", ",")

val df = fileReader.load(PATH_TO_FILE)
Run Code Online (Sandbox Code Playgroud)