Pyspark模式和可选字段上的多个框架交互

gab6jxml  于 2024-01-06  发布在  Spark
关注(0)|答案(1)|浏览(138)

大家早上好,关于模式和pyspark框架的快速问题。假设我从一个模式开始,并使用该模式将数据从文件加载到一个pyspark框架中。到目前为止,一切顺利。
然而,我注意到,当一个可选字段(在模式上为nullable=true)在我的数据中根本不存在时,pyspark只是不将其包含在模式中(而不是将其值设置为null),所以当我稍后对该字段进行选择时,我的代码会卡住。
所以我的问题是,有没有一种方法可以让pyspark在schema中创建每个元素,并在它们不存在时将它们设置为null,而不是仅仅从schema中删除它们?

4ngedf3f

4ngedf3f1#

当阅读具有指定架构的CSV文件时,文件中的数据可能与架构不匹配。

**PERMISSIVE(默认):为无法正确解析的字段插入空值DROPMALFORMED:删除包含无法解析的字段的行FAILFAST:**如果发现任何格式错误的数据,则中止阅读要设置模式,请使用mode选项。
示例数据和模式:

repair_request_schema = StructType([
    StructField("request_id", StringType(), nullable=True),
    StructField("customer_name", StringType(), nullable=True),
    StructField("repair_type", StringType(), nullable=True),
    StructField("repair_cost", IntegerType(), nullable=True),
])
repair_request_data = [
    ("1", "John Doe", "Electrical", 200),
    ("2", "Jane Smith", "Plumbing", None)
]

字符串
我尝试了下面的例子:

read_repair_request_df = (
    spark.read.option("mode", "PERMISSIVE")
    .schema(repair_request_schema)
    .csv("/FileStore/tables/repair_req.csv")
)
read_repair_request_df.show()

结果:

+----------+-------------+-----------+-----------+
|request_id|customer_name|repair_type|repair_cost|
+----------+-------------+-----------+-----------+
|         1|     John Doe| Electrical|        200|
|         2|   Jane Smith|   Plumbing|       NULL|
+----------+-------------+-----------+-----------+


PERMISSIVE模式将通过将字段设置为null来处理丢失的字段。
PERMISSIVE模式下,可以使用以下方法之一来检查无法正确解析的行:
您可以为选项badRecordsPath提供自定义路径,以将损坏的记录到文件中。您可以将column _corrupt_record添加到提供给DataFrameReader的架构中,以查看生成的DataFrame中的损坏记录。

参考:

处理格式错误的CSV记录

**第二种方法:**使用fillna方法将空值填充为默认值。

from pyspark.sql.types import StructType, StructField, StringType, IntegerType
from pyspark.sql.functions import col
schema =  StructType([
StructField("name", StringType(), True),
StructField("age", IntegerType(), True),
StructField("gender", StringType(), True)
])
data = [("Alice", 25, "F"), (None, None, "M"), ("Bob", 30, None)]
df = spark.createDataFrame(data, schema)
df = df.fillna({"name": "Unknown", "age": -1, "gender": "Unknown"})
df.select(col("name"), col("age"), col("gender")).show()


结果如下:

+-------+---+-------+
|   name|age| gender|
+-------+---+-------+
|  Alice| 25|      F|
|Unknown| -1|      M|
|    Bob| 30|Unknown|
+-------+---+-------+

相关问题