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

时间:2017-05-24 23:42:50

标签: scala apache-spark apache-spark-sql spark-dataframe

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

我试图通过程序化方法创建Schema:

val schema = StructType(header.split(",").map(column => StructField(column, StringType, true)))

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

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)))

但是当我使用DF.show()创建DataFrame后,它会给Integer字段带来错误。

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

2 个答案:

答案 0 :(得分:3)

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

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

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

val header = "field1:Int,field2:Double,field3:String"

然后代码应该是

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)))

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

root
 |-- field1:Int: integer (nullable = true)
 |-- field2:Double: double (nullable = true)
 |-- field3:String: string (nullable = true)

另一方面。如果您需要的是来自文本的数据框,我建议您直接从文件本身创建DataFrame。从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)

答案 1 :(得分:1)

首先定义结构类型:

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

然后通过将每个列转换为特定类型来指定要在行中出现的每个列:

val auctionDF = spark.sqlContext.createDataFrame(dataRdd,schema1)

然后将Schema应用于RDD

y(t) = a*e^t + b*e^t + c*e^t