更改现有数据框的架构

use*_*576 9 scala dataframe apache-spark

我想更改现有数据帧的架构,同时更改我遇到错误的架构。我是否可以更改数据帧的现有架构。

val customSchema=StructType(
      Array(
        StructField("data_typ", StringType, nullable=false),
        StructField("data_typ", IntegerType, nullable=false),
        StructField("proc_date", IntegerType, nullable=false),
        StructField("cyc_dt", DateType, nullable=false),
        ));

val readDF=
+------------+--------------------+-----------+--------------------+
|DatatypeCode|         Description|monthColNam|     timeStampColNam|
+------------+--------------------+-----------+--------------------+
|       03099|Volumetric/Expand...|     201867|2018-05-31 18:25:...|
|       03307|  Elapsed Day Factor|     201867|2018-05-31 18:25:...|
+------------+--------------------+-----------+--------------------+

val rows= readDF.rdd
val readDF1 = sparkSession.createDataFrame(rows,customSchema)
Run Code Online (Sandbox Code Playgroud)

预期结果

val newdf=
    +------------+--------------------+-----------+--------------------+
    |data_typ_cd |       data_typ_desc|proc_dt    |     cyc_dt         |
    +------------+--------------------+-----------+--------------------+
    |       03099|Volumetric/Expand...|     201867|2018-05-31 18:25:...|
    |       03307|  Elapsed Day Factor|     201867|2018-05-31 18:25:...|
    +------------+--------------------+-----------+--------------------+
Run Code Online (Sandbox Code Playgroud)

任何帮助将被应用

Pra*_*ode 9

您可以执行类似操作以将数据类型从一种更改为另一种。

我创建了一个类似于你的数据框,如下所示:

import sparkSession.sqlContext.implicits._
import org.apache.spark.sql.types._

var df = Seq(("03099","Volumetric/Expand...", "201867", "2018-05-31 18:25:00"),("03307","Elapsed Day Factor", "201867", "2018-05-31 18:25:00"))
  .toDF("DatatypeCode","data_typ", "proc_date", "cyc_dt")

df.printSchema()
df.show()
Run Code Online (Sandbox Code Playgroud)

这给了我以下输出:

root
 |-- DatatypeCode: string (nullable = true)
 |-- data_typ: string (nullable = true)
 |-- proc_date: string (nullable = true)
 |-- cyc_dt: string (nullable = true)

+------------+--------------------+---------+-------------------+
|DatatypeCode|            data_typ|proc_date|             cyc_dt|
+------------+--------------------+---------+-------------------+
|       03099|Volumetric/Expand...|   201867|2018-05-31 18:25:00|
|       03307|  Elapsed Day Factor|   201867|2018-05-31 18:25:00|
+------------+--------------------+---------+-------------------+
Run Code Online (Sandbox Code Playgroud)

如果您在上方看到架构,则所有列都是字符串类型。现在我想改列proc_dateInteger打字和cyc_dtDate类型,我将做到以下几点:

df = df.withColumnRenamed("DatatypeCode", "data_type_code")

df = df.withColumn("proc_date_new", df("proc_date").cast(IntegerType)).drop("proc_date")

df = df.withColumn("cyc_dt_new", df("cyc_dt").cast(DateType)).drop("cyc_dt")
Run Code Online (Sandbox Code Playgroud)

当您检查此数据框的架构时

df.printSchema()
Run Code Online (Sandbox Code Playgroud)

然后它使用新的列名给出如下输出:

root
 |-- data_type_code: string (nullable = true)
 |-- data_typ: string (nullable = true)
 |-- proc_date_new: integer (nullable = true)
 |-- cyc_dt_new: date (nullable = true)
Run Code Online (Sandbox Code Playgroud)

  • 优先选择 `col("columnName")` 而不是 `df("columnName")`,这样您就可以避免对数据框名称的内部引用,并且可以以流畅的方式将代码编写为单个表达式。 (2认同)

小智 7

您不能像这样更改架构。传递给的架构对象createDataFrame必须匹配数据,而不是相反: