使用Python类中的方法作为PySpark用户定义函数

时间:2018-10-01 19:13:54

标签: python apache-spark pyspark apache-spark-sql user-defined-functions

我正在尝试编写一个Python实用程序函数,该函数接受PySpark DataFrame withColumn调用中的本地定义类的对象,并将该类的方法之一用作用户定义函数(UDF)。 。实用程序功能签名为:

 def spark_analyze(lp: LogProcessor):

LogProcessor类中,我有一个想用作UDF的方法。方法定义为:

schema = StructType([
  StructField("total", IntegerType(), False),
  StructField("other", IntegerType(), False)
])

def ProcessLog(self, log_file):
    self.PrepareForLog()
    for event in pyspark_utils.spark_events_from_file(log_file):
      self.ProcessEvent(event)
      return [total, other]

spark_analyze中,我执行以下操作,其中lp是类型LogProcessor的传入对象:

@udf(lp.schema)
def lpf(lcm_file):
    lp.ProcessLog(lcm_file)
return (df.withColumn('results', lpf(col('logfile_dir')))
...

这会产生一个很长的Python堆栈跟踪,其开始如下:

/home/david/libs.zip/pyspark_utils.py在spark_analyze(lp)中     132 def lpf(lcm_file):     133.lp.ProcessLog(lcm_file) -> 134 return(df.withColumn('results',lpf(col('logfile_dir'))))     135 .withColumn('日志名称',spark_get_dataset_name(col('logfile_dir')))     136 .select('log name','results。*')

包装中的

/usr/hdp/current/spark2-client/python/lib/pyspark.zip/pyspark/sql/functions.py(* args)    1955 @ functools.wraps(f)    1956年def包装器(* args): -> 1957年返回udf_obj(* args)    1958年    1959 wrapper.func = udf_obj.func

结尾为:

/home/david/libs.zip/pyspark_utils.py在spark_analyze(lp)中     132 def lpf(lcm_file):     133.lp.ProcessLog(lcm_file) -> 134 return(df.withColumn('results',lpf(col('logfile_dir'))))     135 .withColumn('日志名称',spark_get_dataset_name(col('logfile_dir')))     136 .select('log name','results。*')

包装中的

/usr/hdp/current/spark2-client/python/lib/pyspark.zip/pyspark/sql/functions.py(* args)    1955 @ functools.wraps(f)    1956年def包装器(* args): -> 1957年返回udf_obj(* args)    1958年    1959 wrapper.func = udf_obj.func

我做了一些测试,发现如果在将UDF传递给col的位置上方定义UDF,则一切正常。我还尝试将ProcessLog重新定义为return [0,0],发现问题并没有消失。所以问题似乎是我正在使用传入的类对象的方法作为UDF。还有另一种方法可以让UDF成为类中的方法吗?感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

Usman Azhar建议的方法可能有效。我最终通过简单地将UDF的定义作为库函数的参数传递来解决了这个问题。