我可以更改Spark数据框中的列的可空性吗?


问题内容

我在一个不能为空的数据框中有一个StructField。简单的例子:

import pyspark.sql.functions as F
from pyspark.sql.types import *
l = [('Alice', 1)]
df = sqlContext.createDataFrame(l, ['name', 'age'])
df = df.withColumn('foo', F.when(df['name'].isNull(),False).otherwise(True))
df.schema.fields

返回:

[StructField(name,StringType,true),StructField(age,LongType,true),StructField(foo,BooleanType,false)]

请注意,该字段foo不可为空。问题是(出于我不愿讨论的原因)我希望它可以为空。我发现这篇文章在spark数据帧中更改了column的null属性,它建议了一种方法,因此我将其中的代码调整为:

import pyspark.sql.functions as F
from pyspark.sql.types import *
l = [('Alice', 1)]
df = sqlContext.createDataFrame(l, ['name', 'age'])
df = df.withColumn('foo', F.when(df['name'].isNull(),False).otherwise(True))
df.schema.fields
newSchema = [StructField('name',StringType(),True), StructField('age',LongType(),True),StructField('foo',BooleanType(),False)]
df2 = sqlContext.createDataFrame(df.rdd, newSchema)

失败了:

TypeError:StructField(name,StringType,true)不可序列化JSON

我也在堆栈跟踪中看到了这一点:

引发ValueError(“检测到循环参考”)

所以我有点卡住了。谁能以允许我定义column可以foo为空的数据框的方式修改此示例?


问题答案:

似乎您错过了StructType(newSchema)。

l = [('Alice', 1)]
df = sqlContext.createDataFrame(l, ['name', 'age'])
df = df.withColumn('foo', F.when(df['name'].isNull(),False).otherwise(True))
df.schema.fields
newSchema = [StructField('name',StringType(),True), StructField('age',LongType(),True),StructField('foo',BooleanType(),False)]
df2 = sqlContext.createDataFrame(df.rdd, StructType(newSchema))
df2.show()