在Pandas UDF函数中无法识别的函数

时间:2020-05-10 00:10:46

标签: python pyspark user-defined-functions

我正在Pyspark上使用Pandas UDF。

我有一个主文件 __ main_.py ,其中:

from pyspark.sql import SparkSession
from run_udf import compute


def main():
    spark = SparkSession.builder.getOrCreate()
    df = spark.createDataFrame(
        [(1, 1.0), (1, 2.0), (2, 3.0), (2, 5.0), (2, 10.0)],
        ("id", "v"))
    df = compute(df)
    df.show()
    spark.stop()


if __name__ == "__main__":
    main()

还有一个 run_udf.py 文件,其中包含我的UDF函数和另一个函数(将单个变量乘以2):

from pyspark.sql.functions import pandas_udf, PandasUDFType


def multi_by_2(x):
    return 2 * x


def compute(df):

    @pandas_udf("id long, v double", PandasUDFType.GROUPED_MAP)
    def subtract_mean(pdf):
        # pdf is a pandas.DataFrame
        v = pdf.v
        return pdf.assign(v=multi_by_2(v) - v.mean())

    df = df.groupby("id").apply(subtract_mean)

    return df

通过运行main.py,我得到以下错误:“没有名为'run_udf'的模块”。 在这种配置中,subtract_mean()似乎没有访问函数multi_by_2()。我发现了两种方法,但不知道它是否遵循最佳实践标准:

方法1:(将函数移到计算机内部-并不理想,因为每次使用另一个pandas_udf()函数时我都会复制该函数-我们松开了“可重用”函数的概念)

def compute(df):
    def multi_by_2(x):
        return 2 * x
    @pandas_udf("id long, v double", PandasUDFType.GROUPED_MAP)
    def subtract_mean(pdf):
        # pdf is a pandas.DataFrame
        v = pdf.v
        return pdf.assign(v=multi_by_2(v) - v.mean())

    df = df.groupby("id").apply(subtract_mean)


    return df

方法2:将乘法函数作为计算参数。

__ main_.py

from pyspark.sql import SparkSession
from run_udf import compute
def multi_by_2(x):
    return 2 * x

def main():
    spark = SparkSession.builder.getOrCreate()
    df = spark.createDataFrame(
        [(1, 1.0), (1, 2.0), (2, 3.0), (2, 5.0), (2, 10.0)],
        ("id", "v"))
    df = compute(df, multi_by_2)
    df.show()
    spark.stop()


if __name__ == "__main__":
    main()

run_udf.py 从pyspark.sql.functions导入pandas_udf,PandasUDFType

def compute(df, multi_by_2):
    @pandas_udf("id long, v double", PandasUDFType.GROUPED_MAP)
    def subtract_mean(pdf):
        # pdf is a pandas.DataFrame
        v = pdf.v
        return pdf.assign(v=multi_by_2(v) - v.mean())

    df = df.groupby("id").apply(subtract_mean)


    return df

我发现这两个解决方案似乎有些古怪。有没有更好的方法来解决这个问题?

0 个答案:

没有答案