我可以更改Spark DataFrame中列的无效性吗?



我在数据框架中有一个无法确定的结构字段。简单示例:

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(年龄,Longtype,true), structfield(foo,booleantype,false)]

请注意,字段foo不能无效。问题是(由于我不会进入的原因),我希望它能无效。我发现这篇文章更改了Spark DataFrame中的列的无效属性,这建议了一种方法,因此我对其中的代码进行了调整:

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 serializable

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

提高ValueError("检测到的圆形参考")

所以我有点卡住。任何人都可以通过使我能够定义一个数据框的方式修改此示例,其中foo可以在其中列出?

我知道这个问题已经回答了,但是当我提出这个问题时,我正在寻找一个更通用的解决方案:

def set_df_columns_nullable(spark, df, column_list, nullable=True):
    for struct_field in df.schema:
        if struct_field.name in column_list:
            struct_field.nullable = nullable
    df_mod = spark.createDataFrame(df.rdd, df.schema)
    return df_mod

您可以这样称呼:

set_df_columns_nullable(spark,df,['name','age'])

对于一般情况,可以通过该特定列的StructFieldnullable属性更改列的无效性。这是一个例子:

df.schema['col_1']
# StructField(col_1,DoubleType,false)
df.schema['col_1'].nullable = True
df.schema['col_1']
# StructField(col_1,DoubleType,true)

似乎您错过了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()
df1 = df.rdd.toDF()
df1.printSchema()

输出:

root
 |-- name: string (nullable = true)
 |-- age: long (nullable = true)
 |-- foo: boolean (nullable = true)

相关内容

  • 没有找到相关文章

最新更新