PySpark:StructField(..., ..., False) 总是返回 `nullable=true` 而不是 `nullable=false`
Posted
技术标签:
【中文标题】PySpark:StructField(..., ..., False) 总是返回 `nullable=true` 而不是 `nullable=false`【英文标题】:PySpark: StructField(..., ..., False) always returns `nullable=true` instead of `nullable=false` 【发布时间】:2016-10-07 12:15:24 【问题描述】:我是 PySpark 的新手,遇到了一个奇怪的问题。我正在尝试在加载 CSV 数据集时将某些列设置为不可为空。我可以用非常小的数据集 (test.csv
) 重现我的案例:
col1,col2,col3
11,12,13
21,22,23
31,32,33
41,42,43
51,,53
第 5 行第 2 列有一个空值,我不想在我的 DF 中获取该行。我将所有字段设置为不可为空(nullable=false
),但我得到了一个架构,其中所有三列都具有nullable=true
。即使我将所有三列都设置为不可为空,也会发生这种情况!我正在运行 Spark 的最新可用版本 2.0.1。
代码如下:
from pyspark.sql import SparkSession
from pyspark.sql.functions import *
from pyspark.sql.types import *
spark = SparkSession \
.builder \
.appName("Python Spark SQL basic example") \
.config("spark.some.config.option", "some-value") \
.getOrCreate()
struct = StructType([ StructField("col1", StringType(), False), \
StructField("col2", StringType(), False), \
StructField("col3", StringType(), False) \
])
df = spark.read.load("test.csv", schema=struct, format="csv", header="true")
df.printSchema()
返回:
root
|-- col1: string (nullable = true)
|-- col2: string (nullable = true)
|-- col3: string (nullable = true)
和df.show()
返回:
+----+----+----+
|col1|col2|col3|
+----+----+----+
| 11| 12| 13|
| 21| 22| 23|
| 31| 32| 33|
| 41| 42| 43|
| 51|null| 53|
+----+----+----+
虽然我期望这样:
root
|-- col1: string (nullable = false)
|-- col2: string (nullable = false)
|-- col3: string (nullable = false)
+----+----+----+
|col1|col2|col3|
+----+----+----+
| 11| 12| 13|
| 21| 22| 23|
| 31| 32| 33|
| 41| 42| 43|
+----+----+----+
【问题讨论】:
我不认为这个问题已经完全按照issues.apache.org/jira/browse/SPARK-10848解决了 【参考方案1】:虽然 Spark 行为(从 False
切换到 True
令人困惑,但这里并没有发生根本性的错误。nullable
参数不是约束,而是源和类型语义的反映,它启用某些类型的优化
您声明要避免数据中出现空值。为此,您应该使用na.drop
方法。
df.na.drop()
有关处理空值的其他方法,请查看DataFrameNaFunctions
(使用DataFrame.na
属性公开)文档。
CSV 格式不提供任何允许您指定数据约束的工具,因此根据定义,阅读器不能假定输入不为空并且您的数据确实包含空值。
【讨论】:
这不是应该被视为错误的东西吗?你怎么能把某些东西专门设置为假,但在内部更改为真。这甚至发生在不包含任何空值开头的数据帧上。 我同意@Joop。 DataFrame 没有像我们预期的那样执行(也就是说,如果我明确要求 False,我确实想要 nullable = false)。这仍然是 Spark 中的一个问题并且尚未修复吗?我浏览了 Spark 源代码,但没有看到任何解决此问题的地方。我错过了修复吗? 这个答案不满意 我同意这个设计决定是违反直觉的。如果我在我的模式中明确设置一个字段不可为空,我希望数据符合这个模式限制,如果我在加载数据时设置选项“FAILFAST”,当非 Nuallbe 字段有时程序应该抛出异常空值。以上是关于PySpark:StructField(..., ..., False) 总是返回 `nullable=true` 而不是 `nullable=false`的主要内容,如果未能解决你的问题,请参考以下文章