PySparkのWindowにユーザー定義関数を適用しようとしています。 UDAFが進むべき道かもしれないと読みましたが、具体的なものは何も見つかりませんでした。
例を挙げると(ここから引用: Xinh's Tech Blog そしてPySpark用に変更):
from pyspark import SparkConf
from pyspark.sql import SparkSession
from pyspark.sql.window import Window
from pyspark.sql.functions import avg
spark = SparkSession.builder.master("local").config(conf=SparkConf()).getOrCreate()
a = spark.createDataFrame([[1, "a"], [2, "b"], [3, "c"], [4, "d"], [5, "e"]], ['ind', "state"])
customers = spark.createDataFrame([["Alice", "2016-05-01", 50.00],
["Alice", "2016-05-03", 45.00],
["Alice", "2016-05-04", 55.00],
["Bob", "2016-05-01", 25.00],
["Bob", "2016-05-04", 29.00],
["Bob", "2016-05-06", 27.00]],
["name", "date", "amountSpent"])
customers.show()
window_spec = Window.partitionBy("name").orderBy("date").rowsBetween(-1, 1)
result = customers.withColumn( "movingAvg", avg(customers["amountSpent"]).over(window_spec))
result.show()
すでにpyspark.sql.functions
に組み込まれているavg
を適用していますが、avg
の代わりにもっと複雑なものを使用して独自の関数を作成したい場合は、どうすればよいですか?
Spark> = 3.0:
SPARK-24561 -pandas udf(有界ウィンドウ)を使用したユーザー定義のウィンドウ関数は進行中の作業です。詳細については、関連するJIRAに従ってください。
Spark> = 2.4:
SPARK-22239 -pandas udf(無制限ウィンドウ)を使用したユーザー定義ウィンドウ関数でPandasのサポートが導入されました_無制限のウィンドウを持つベースのウィンドウ関数。一般的な構造は
return_type: DataType
@pandas_udf(return_type, PandasUDFType.GROUPED_AGG)
def f(v):
return ...
w = (Window
.partitionBy(grouping_column)
.rowsBetween(Window.unboundedPreceding, Window.unboundedFollowing))
df.withColumn('foo', f('bar').over(w))
詳細な例については、 doctests および nit tests を参照してください。
Spark <2.4
それはいけません。ウィンドウ関数には、UserDefinedAggregateFunction
ではなくUserDefinedFunction
または同等のオブジェクトが必要であり、PySparkで定義することはできません。
ただし、PySpark 2.3以降では、グループ化されたデータに適用できるベクトル化されたpandas_udf
を定義できます。実用的な例を見つけることができます PySparkのGroupedDataにUDFを適用する(機能するpythonの例を使用) 。 Pandasはウィンドウ関数に直接相当するものを提供しませんが、特に pandas.DataFrame.rolling
を使用すると、ウィンドウのようなロジックを実装するのに十分な表現力があります。さらに、GroupedData.apply
で使用される関数は、任意の数の行を返すことができます。
PySparkからScala UDAFを呼び出すこともできます Spark:PythonをScalaまたはJavaユーザー定義関数にマッピングする方法は? 。