Pyspark 数据帧写入和读取更改架构

Posted

技术标签:

【中文标题】Pyspark 数据帧写入和读取更改架构【英文标题】:Pyspark dataframe write and read changes schema 【发布时间】:2020-07-28 20:52:39 【问题描述】:

我有一个包含 string 和 int 列的 spark 数据框。

但是当我将数据框写入 csv 文件并稍后加载时,所有列都作为字符串加载。

from pyspark.sql import SparkSession
spark = SparkSession.builder.enableHiveSupport().getOrCreate()
df = spark.createDataFrame([("Alberto", 2), ("Dakota", 2)], 
                              ["Name", "count"])

之前:

df.printSchema()

输出:

root
  |-- Name: string (nullable = true)
  |-- count: long (nullable = true)


df.write.mode('overwrite').option('header', True).csv(filepath)

new_df = spark.read.option('header', True).csv(filepath)

之后:

new_df.printSchema()

输出:

root
  |-- Name: string (nullable = true)
  |-- count: string (nullable = true)

如何在编写时指定存储模式?

【问题讨论】:

【参考方案1】:

我们在写作时don't have to specify schema,但我们可以在阅读时指定schema

Example:

from pyspark.sql.types import *
from pyspark.sql.functions import *
schema = StructType(
   [
     StructField('Name', StringType(), True),
    StructField('count', LongType(), True)
   ]
 )

#specify schema while reading
new_df = spark.read.schema(schema).option('header', True).csv(filepath)
new_df.printSchema()

#or else use inferschema option as true but specifying schema will be more robust
new_df = spark.read.option('header', True).option("inferSchema",True).csv(filepath)

【讨论】:

我在加载文件时事先并不知道所有的列名。我可以将一列指定为字符串,然后将所有其他列默认为长吗? @ThirupathiThangavel,那么最好使用inferSchema 选项,在这种情况下我们不需要知道之前的所有列名(或)否则您需要动态构建架构 然后在使用 .schema 选项读取 csv 文件时传递架构。

以上是关于Pyspark 数据帧写入和读取更改架构的主要内容,如果未能解决你的问题,请参考以下文章

Pyspark 数据帧从一个存储桶中读取,并在同一作业中使用不同的 KMS 密钥写入另一个存储桶

在 PySpark 中写入镶木地板的问题

为 pyspark 数据帧的每一行评估多个 if elif 条件

Pyspark 数据框:将 jdbc 写入具有给定模式的表的动态创建

pyspark:数据帧写入镶木地板

使用 pyspark 将数据帧写入 Kafka 时出现异常