Is there anyway to use it as a standard function located in package org.apache.spark.sql.functions._ ?
For now it is intended only for usage with SQL expressions, although if you want to return a Column
your use expr
:
org.apache.spark.sql.functions._
expr("transform(i, x -> x + 1)"): Column
Using it this way is there anyway to provide a custom function for the transformation?
It is possible to use Scala UDF*:
spark.udf.register("f", (x: Int) => x + 1)
Seq((1, Seq(1, 2, 3))).toDF("id", "xs")
.withColumn("xsinc", expr("transform(xs, x -> f(x))"))
.show
+---+---------+---------+
| id| xs| xsinc|
+---+---------+---------+
| 1|[1, 2, 3]|[2, 3, 4]|
+---+---------+---------+
although it doesn't seem to provide any real benefits over UDF taking a Seq
.
* A partial support for Python UDFs seem to be in place (udfs are recognized, types are correctly derived, and calls are dispatched) as well, but as of 2.4.0 the serialization mechanism seems to be broken (all records are passed to UDF as None
):
from typing import Optional
from pyspark.sql.functions import expr
sc.version
'2.4.0'
def f(x: Optional[int]) -> Optional[int]:
return x + 1 if x is not None else None
spark.udf.register('f', f, "integer")
df = (spark
.createDataFrame([(1, [1, 2, 3])], ("id", "xs"))
.withColumn("xsinc", expr("transform(xs, x -> f(x))")))
df.printSchema()
root
|-- id: long (nullable = true)
|-- xs: array (nullable = true)
| |-- element: long (containsNull = true)
|-- xsinc: array (nullable = true)
| |-- element: integer (containsNull = true)
df.show()
+---+---------+-----+
| id| xs|xsinc|
+---+---------+-----+
| 1|[1, 2, 3]| [,,]|
+---+---------+-----+
Of course there is no real potential for performance boost here - it dispatches to BasePythonRunner
so overhead should be the same as of plain udf
.
Related JIRA ticket SPARK-27052 - Using PySpark udf in transform yields NULL values