Apache spark 为什么在ApacheSparkSQL中列变为可空?
为什么在执行某些函数后使用Apache spark 为什么在ApacheSparkSQL中列变为可空?,apache-spark,apache-spark-sql,apache-spark-dataset,Apache Spark,Apache Spark Sql,Apache Spark Dataset,为什么在执行某些函数后使用nullable=true,即使数据帧中没有NaN值 val myDf=Seq((2,“A”),(2,“B”),(1,“C”)) .toDF(“foo”、“bar”) .withColumn(“foo”),“foo.cast(“Int”)) myDf.withColumn(“foo_2”,当($“foo”==2,1)时。否则(0))。选择(“foo”,“foo_2”)。显示 现在调用df.printSchema时,两列的null将为false valfoo:(Int=
nullable=true
,即使数据帧中没有NaN值
val myDf=Seq((2,“A”),(2,“B”),(1,“C”))
.toDF(“foo”、“bar”)
.withColumn(“foo”),“foo.cast(“Int”))
myDf.withColumn(“foo_2”,当($“foo”==2,1)时。否则(0))。选择(“foo”,“foo_2”)。显示
现在调用df.printSchema
时,两列的null
将为false
valfoo:(Int=>String)=(t:Int)=>{
fooMap.get(t)匹配{
案例部分(tt)=>tt
案例无=>“未找到”
}
}
val fooMap=Map(
1->“小”,
2->“大”
)
val fooUDF=udf(foo)
myDf
.withColumn(“foo”,fooUDF(col(“foo”))
。使用列(“foo_2”,当($“foo”==2,1)。否则(0)。选择(“foo”,“foo_2”)
.选择(“foo”、“foo_2”)
.printSchema
但是现在,nullable
对于至少一个以前为false
的列是true
。如何解释这一点?当从静态类型结构(不依赖于模式
参数)创建数据集
时,Spark使用一组相对简单的规则来确定可空的
属性
- 如果给定类型的对象可以是
null
,则其DataFrame
表示形式为null
- 如果对象是
选项[\u]
,则其数据帧
表示为可空
,且无
被视为SQL空
- 在任何其他情况下,它将被标记为不可为空
由于ScalaString
是java.lang.String
,可以是null
,所以生成的列可以是null
。出于同样的原因,bar
列在初始数据集中为null
:
val data1=Seq[(Int,String)]((2,“A”),(2,“B”),(1,“C”))
val df1=data1.toDF(“foo”,“bar”)
df1.schema(“bar”).nullable
Boolean=true
但是foo
不是(scala.Int
不能是null
)
df1.schema(“foo”).nullable
Boolean=false
如果我们将数据定义更改为:
val data2=Seq[(整数,字符串)]((2,“A”),(2,“B”),(1,“C”))
foo
将是null
(Integer
是java.lang.Integer
,装箱整数可以是null
):
data2.toDF(“foo”,“bar”).schema(“foo”).nullable
Boolean=true
另请参见:修改ScalaUDF以处理可空性。您也可以非常快速地更改dataframe的架构。像这样的东西就行了-
def setNullableStateForAllColumns( df: DataFrame, columnMap: Map[String, Boolean]) : DataFrame = {
import org.apache.spark.sql.types.{StructField, StructType}
// get schema
val schema = df.schema
val newSchema = StructType(schema.map {
case StructField( c, d, n, m) =>
StructField( c, d, columnMap.getOrElse(c, default = n), m)
})
// apply new schema
df.sqlContext.createDataFrame( df.rdd, newSchema )
}