【问题标题】:Extract First Non-Null Positive Element From Array in PySpark从 PySpark 中的数组中提取第一个非 Null 正元素
【发布时间】:2020-10-05 10:05:17
【问题描述】:

我有如下数据:

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”数组中第一个非零元素的新列,或者为空。在这种情况下:

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: '>=' not supported between 'NoneType' and 'int'

【问题讨论】:

    标签: pyspark apache-spark-sql


    【解决方案1】:

    通过将 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()
    

    【讨论】:

      猜你喜欢
      • 2021-12-22
      • 2023-04-08
      • 2017-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多