【问题标题】:Spark UDF that takes in unknown number of columns接受未知列数的 Spark UDF
【发布时间】:2016-12-12 15:01:23
【问题描述】:

我有一个具有不同架构的 spark 数据框列表。示例:

list_df = [df1, df2, df3, df4]
# df1.columns = ['a', 'b']
# df2.columns = ['a', 'b', 'c']
# df3.columns = ['a', 'b', 'c', 'd']
# df4.columns = ['a', 'b', 'c', 'd', 'e']

现在,我想编写一个 udf,它能够对具有不同列数的数据帧列表进行操作。

之前有一篇关于如何使用 scala 的帖子:Spark UDF with varargs,其中 udf 接受一个列数组。

但似乎该方法不适用于python。有什么建议吗?

谢谢。

【问题讨论】:

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


    【解决方案1】:

    实际上这种方法在 Python 中效果很好:

    from pyspark.sql.functions import array, udf
    
    df = sc.parallelize([("a", "b", "c", "d")]).toDF()
    
    f = udf(lambda xs: "+".join(xs))
    
    df.select(f("_1")).show()
    ## +------------+
    ## |<lambda>(_1)|
    ## +------------+
    ## |           a|
    ## +------------+
    
    df.select(f(array("_1", "_2"))).show()
    ## +-----------------------+
    ## |<lambda>(array(_1, _2))|
    ## +-----------------------+
    ## |                    a+b|
    ## +-----------------------+
    
    df.select(f(array("_1", "_2", "_3"))).show()
    ## +---------------------------+
    ## |<lambda>(array(_1, _2, _3))|
    ## +---------------------------+
    ## |                      a+b+c|
    ## +---------------------------+
    

    由于 Python UDF 与 Scala 对应的实体类型不同,因此不受输入参数类型和数量的限制,您也可以使用 args:

    g = udf(lambda *xs: "+".join(xs))
    
    df.select(g("_1", "_2", "_3", "_4")).show()
    ## +------------------------+
    ## |<lambda>(_1, _2, _3, _4)|
    ## +------------------------+
    ## |                 a+b+c+d|
    ## +------------------------+
    

    避免使用array 包装输入。

    您还可以使用struct 作为替代包装器来访问列名:

    h = udf(lambda row: "+".join(row.asDict().keys()))
    
    df.select(h(struct("_1", "_2", "_3"))).show()
    ## +----------------------------+
    ## |<lambda>(struct(_1, _2, _3))|
    ## +----------------------------+
    ## |                    _1+_3+_2|
    ## +----------------------------+
    

    【讨论】:

    • 一个相关问题:有没有办法访问 udf 中的列名,以便我能够从正确的字段中获取值?谢谢。
    • 你可以用struct试试。
    猜你喜欢
    • 1970-01-01
    • 2017-06-11
    • 2019-02-01
    • 2016-12-24
    • 2017-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多