Apache spark 要应用于PySpark中窗口的用户定义函数?

Apache spark 要应用于PySpark中窗口的用户定义函数?,apache-spark,pyspark,aggregate-functions,user-defined-functions,window-functions,Apache Spark,Pyspark,Aggregate Functions,User Defined Functions,Window Functions,我正在尝试将用户定义的函数应用于PySpark中的窗口。我读到UDAF可能是一条路要走,但我找不到任何具体的东西 要给出一个示例(取自此处:并针对PySpark进行了修改): 来自pyspark导入SparkConf 从pyspark.sql导入SparkSession 从pyspark.sql.window导入窗口 从pyspark.sql.functions导入平均值 spark=SparkSession.builder.master(“本地”).config(conf=SparkConf(

我正在尝试将用户定义的函数应用于PySpark中的窗口。我读到UDAF可能是一条路要走,但我找不到任何具体的东西

要给出一个示例(取自此处:并针对PySpark进行了修改):

来自pyspark导入SparkConf
从pyspark.sql导入SparkSession
从pyspark.sql.window导入窗口
从pyspark.sql.functions导入平均值
spark=SparkSession.builder.master(“本地”).config(conf=SparkConf()).getOrCreate()
a=spark.createDataFrame([[1,“a”],[2,“b”],[3,“c”],[4,“d”],[5,“e”],['ind',“state”])
客户=spark.createDataFrame([[“Alice”,“2016-05-01”,50.00],
[“爱丽丝”,“2016-05-03”,45.00],
[“爱丽丝”,“2016-05-04”,55.00],
[“北京银行”,“2016-05-01”,25.00],
[“北京银行”,“2016-05-04”,29.00],
[“北京银行”,“2016-05-06”,27.00],
[“姓名”、“日期”、“花费金额”])
customers.show()
window_spec=window.partitionBy(“名称”).orderBy(“日期”).rowsBetween(-1,1)
结果=客户。带列(“移动VG”,平均(客户[“金额花费”])。超过(窗口规格))
result.show()

我正在应用
avg
,它已经内置在
pyspark.sql.functions
中,但是如果我不想使用
avg
而是想使用更复杂的东西并编写我自己的函数,我该怎么做呢?

Spark>=3.0

-用户定义的带有pandas udf(有界窗口)的窗口函数是一项正在进行的工作。请遵循相关JIRA了解详细信息

火花>=2.4

-具有pandas udf(无界窗口)的用户定义窗口函数引入了对具有无界窗口的基于pandas的窗口函数的支持。总体结构是

返回类型:数据类型
@pandas\u udf(返回类型,PandasUDFType.GROUPED\u AGG)
def f(v):
返回。。。
w=(窗口
.partitionBy(分组列)
.rowsBetween(Window.unboundedPreceding,Window.unboundedFollowing))
df.带柱('foo',f('bar')。在(w)上方)
有关详细示例,请参见和

火花<2.4

你不能。窗口函数需要
UserDefinedAggregateFunction
或等效对象,而不是
UserDefinedFunction
,并且不能在PySpark中定义一个

但是,在PySpark 2.3或更高版本中,您可以定义向量化的
pandas\u udf
,它可以应用于分组数据。你可以找到一个有效的例子。虽然Pandas没有提供窗口函数的直接等价物,但它有足够的表现力来实现任何类似窗口的逻辑,特别是在。此外,与
GroupedData.apply一起使用的函数可以返回任意数量的行


您也可以从PySpark调用Scala UDAF。

从Spark 3.0.0开始,UDF现在可以应用于Windows

文件摘录:


from pyspark.sql import Window

@pandas_udf("double")
def mean_udf(v: pd.Series) -> float:
    return v.mean()

df = spark.createDataFrame(
    [(1, 1.0), (1, 2.0), (2, 3.0), (2, 5.0), (2, 10.0)], ("id", "v"))
w = Window.partitionBy('id').orderBy('v').rowsBetween(-1, 0)
df.withColumn('mean_v', mean_udf("v").over(w)).show()

+---+----+------+
| id|   v|mean_v|
+---+----+------+
|  1| 1.0|   1.0|
|  1| 2.0|   1.5|
|  2| 3.0|   3.0|
|  2| 5.0|   4.0|
|  2|10.0|   7.5|
+---+----+------+