如何在Pyspark UDF中返回双精度列表?

时间:2019-11-12 21:27:36

标签: python dataframe pyspark apache-spark-sql pyspark-sql

from pyspark.sql import functions as func

我有一个Pyspark数据框,称为df。它具有以下架构:

id: string
item: string
data: double

我对其进行以下操作:

grouped_df = df.groupBy(["id", "item"]).agg(func.collect_list(df.data).alias("dataList"))

此外,我定义了用户定义的函数iqrOnList

@udf
def iqrOnList(accumulatorsList: list):
  import numpy as np 

  Q1 = np.percentile(accumulatorsList, 25)
  Q3 = np.percentile(accumulatorsList, 75) 
  IQR = Q3 - Q1

  lowerFence = Q1 - (1.5 * IQR)
  upperFence = Q3 + (1.5 * IQR)

  return [elem if (elem >= lowerFence and elem <= upperFence) else None for elem in accumulatorsList]

我以这种方式使用此UDF:

grouped_df = grouped_df.withColumn("SecondList", iqrOnList(grouped_df.dataList))

这些操作在输出中返回数据帧grouped_df,如下所示:

id: string
item: string
dataList: array
SecondList: string

问题

SecondList具有我期望的正确值(例如[1, 2, 3, null, 3, null, 2]),但是返回类型错误(string而不是array,即使它保留了的形式)。

问题是我需要将其存储为array,就像dataList一样。

问题:

1)如何保存正确的类型?

2)此UDF在性能方面很昂贵。 我读过here,说Pandas UDF的性能比普通UDF好得多。熊猫UDF中这种方法的等效性是什么?

奖励问题(优先级较低):func.collect_list(df.data)不会收集null拥有的df.data值。我也想收集它们,没有replacing all null values with another default value怎么办?

1 个答案:

答案 0 :(得分:1)

您仍然可以使用当前语法,只需要在注释声明中提供返回类型即可

import pyspark.sql.types as Types
@udf(returnType=Types.ArrayType(Types.DoubleType()))