【问题标题】:create schema of a array element in scala在scala中创建数组元素的模式
【发布时间】:2020-07-16 21:34:00
【问题描述】:

我是 scala 的新手,并试图从元素数组中创建自定义模式,以基于新的自定义模式读取文件。

我从 json 文件中读取了数组并使用了explode 方法并为列数组中的每个元素创建了一个数据框。

val otherPeople = sqlContext.read.option("multiline", "true").json(otherPeopleDataset)
val column_values = otherPeople.withColumn("columns", explode($"columns")).select("columns.*")
column_values.printSchema()

得到的输出是:

column_values: org.apache.spark.sql.DataFrame = [column_id: string, data_sensitivty: string ... 3 more fields]
root
 |-- column_id: string (nullable = true)
 |-- data_sensitivty: string (nullable = true)
 |-- datatype: string (nullable = true)
 |-- length: string (nullable = true)
 |-- name: string (nullable = true)

val column_name = column_values.select("name","datatype")

column_name: org.apache.spark.sql.DataFrame = [name: string, datatype: string]
column_name.show(4)


+-----------------+--------+
|             name|datatype|
+-----------------+--------+
|    object_number| varchar|
|    function_type| varchar|
|            hof_1| varchar|
|            hof_2| varchar|
|           region| varchar|
|          country| varchar|
+-----------------+--------+

现在对于上面列出的所有值,我想动态创建一个 val 架构。

示例:

val schema = new StructType()
      .add("object_number",StringType,true)
      .add("function_type",StringType,true)
      .add("hof_1",StringType,true)
      .add("hof_2",StringType,true)
      .add("region",StringType,true)
      .add("Country",StringType,true)

我想在获得列数据帧后动态构建以上结构,我读到首先我需要为每个元素创建一个数据类型映射,然后在循环中创建一个结构。由于我对scala的了解有限,有人可以在这里提供帮助吗?

【问题讨论】:

  • 你能显示其他人数据框打印模式吗?也为这个其他人发布相同的数据

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


【解决方案1】:

可以收集带有字段数据的DataFrame,并为每一行添加字段到“StructType”:

val schemaColumns = column_name.collect()
val schema = schemaColumns.foldLeft(new StructType())(
  (schema, columnRow) => schema.add(columnRow.getAs[String]("name"), getFieldType(columnRow.getAs[String]("datatype")), true)
  )

def getFieldType(typeName: String): DataType = typeName match {
    case "varchar" => StringType
    // TODO include other types here
    case _ => StringType
  }

【讨论】:

【解决方案2】:

您可以遵循这种方法,它可以很好地适用于您的示例:

 //The schema is encoded in a string
  val schemaString = "object_number function_type hof_1 hof_2 region Country"
  //Generate the schema based on the string of schema
  val fields = schemaString.split(" ").map(fieldName => StructField(fieldName, StringType, nullable = true))
  val schema = StructType(fields)
  //Convert records of the RDD (myRdd) to Rows
  val rowRDD = sc.textFile("dir").map(line => line.split(",")).map(attributes => Row(attributes(0),attributes(1),attributes(2), attributes(3),attributes(4),attributes(5)))
  //Apply the schema to the RDD
  val perDF = spark.createDataFrame(rowRDD, schema)

【讨论】:

    猜你喜欢
    • 2021-02-15
    • 2019-04-25
    • 1970-01-01
    • 1970-01-01
    • 2014-08-27
    • 1970-01-01
    • 2016-04-26
    • 2016-01-14
    • 2017-01-30
    相关资源
    最近更新 更多