pyspark.sql.utils.AnalysisException: выражения THEN и ELSE должны быть одного типа или приводиться к общему типу. - PullRequest
0 голосов
/ 08 октября 2018

У меня есть следующий код:

import pyspark.sql.functions as func

def get_alert(bid):
    # for simplicity I only provide "return" part
    return "1", "2"

get_alert_udf = func.udf(lambda bid:
       get_alert(bid),
       StructType(
                    [
                        StructField('prob', StringType()),
                        StructField('level', StringType())
                    ]
       )
    )

df = df \
    .withColumn("val", func.when(func.col("is_inside") == 1,
                                 get_alert_udf(
                                                func.col("building_id")
                                               ))
                            .otherwise(func.struct(func.lit("0"),func.lit("0")))

Когда я выполняю этот код, я получаю следующую ошибку:

pyspark.sql.utils.AnalysisException: 
u"cannot resolve 
'CASE WHEN (`is_inside` = 1) 
THEN <lambda>(building_id) ELSE named_struct('col1', '0', 'col2', '0') END' due to data type mismatch: 
THEN and ELSE expressions should all be same type or coercible to a common type

В моем случае выходные данные, похоже, имеют одинаковый типв случае ТО и ДРУГОГО.Я не понимаю, где разница между:

StructType(
                    [
                        StructField('prob', StringType()),
                        StructField('level', StringType())
                    ]
       )

и

func.struct(func.lit("0"),func.lit("0"))

1 Ответ

0 голосов
/ 08 октября 2018

Используемая вами функция возвращает именованную структуру.Это означает, что имена и типы должны совпадать:

func.when(
    func.col("is_inside") == 1,
    get_alert_udf(func.col("building_id"))
).otherwise(
    func.struct(func.lit("0").alias("prob"), func.lit("0").alias("level"))
)

или

schema = StructType([
    StructField('prob', StringType()), StructField('level', StringType())
])

get_alert_udf = func.udf(get_alert, schema)

, а затем

func.when(
    func.col("is_inside") == 1,
    get_alert_udf(func.col("building_id"))
).otherwise(func.struct(func.lit("0"), func.lit("0")).cast(schema))
...