从PySpark中的数组中提取第一个非空正元素

从PySpark中的数组中提取第一个非空正元素,pyspark,apache-spark-sql,Pyspark,Apache Spark Sql,我有如下数据: from pyspark.sql import SparkSession, Row import pyspark.sql.functions as F dd = spark.createDataFrame([ ('0', [Row(f1=0),Row(f1=1),Row(f1=None)]), ('1', [Row(f1=None), Row(f1=2)]), ('2', []) ], ['id', 'arr']) 并希望新列包含“arr”数组中的第一

我有如下数据:

from pyspark.sql import SparkSession, Row
import pyspark.sql.functions as F

dd = spark.createDataFrame([
    ('0', [Row(f1=0),Row(f1=1),Row(f1=None)]),
    ('1', [Row(f1=None), Row(f1=2)]),
    ('2', [])
], ['id', 'arr'])
并希望新列包含“arr”数组中的第一个非零元素,或null。在这种情况下:

id | target_elt
0  | 1
1  | 2
2  | Null
请注意,数组元素的类型为Struct,带有IntegerType字段“f1”

我的尝试:

positiveNonNull = F.udf(
    lambda array: [
        x.f1 for x in array 
        if (x.f1 is not None) & (x.f1 > 0)
    ], ArrayType(LongType())
)
dd.withColumn('newcol', positiveNonNull(F.col('arr')).getItem(0)).show()

我得到TypeError:“>=”在“NoneType”和“int”的实例之间不受支持。

通过将lambda代码包装到帮助程序中解决了这个问题:

def val_if_pos(f1_value):
    if f1_value > 0:
        return f1_value

posNonNull = F.udf(lambda array: [val_if_pos(x.f1) for x in array if x.f1 is not None], ArrayType(LongType()))
(dd.withColumn('_temp', posNonNull(F.col('arr'))
).withColumn('firstPosNonNull', F.expr("FILTER(_temp, x -> x is not null)").getItem(0)
).drop('_temp')
).show()