如何编写可以接受具有可变数量参数的参数的 Pyspark 函数?

How to write Pyspark function that can accept an argument with a variable number of parameters?

提问人:SunflowerParty 提问时间:9/28/2023 更新时间:9/28/2023 访问量:33

问:

我编写了一个我想修改的函数,以具有可以接受一个或多个参数的参数,但是我无法使其正常工作。

def get_recent_date(input_df, *partion_col, order_col):
  w = Window().partitionBy(partition_col)\
  .orderBy(desc(order_col))
  output_df= input_df.withColumn('DenseRank', dense_rank().over(w))
  return output_df

我希望函数运行,以便partition_col可以采用可变数量的参数。在下面的例 1 中,partition_col= 'event_category',在例 2 中,partition_col = 'event_category' 和 'participant_category'。我尝试过以多种方式运行它,但经常收到错误“TypeError:只能将 str(而不是”元组“)连接到 str”。提前感谢您的帮助!

例 1: get_recent_date(输入, 'event_category', 'event_date')

例 2: get_recent_date(输入, 'event_category', 'participant_category', 'event_date')

python 函数 pyspark 参数 variadic-functions

评论


答:

1赞 Simon David 9/28/2023 #1

*partion_col允许您传递可变数量的非关键字参数,其中将所有非关键字参数保存为函数内部。因此,您需要解压缩列名元组,以便正确使用可变长度分区。partion_coltuplepyspark

取代

w = Window().partitionBy(partition_col)\

w = Window().partitionBy(*partition_col)\

你应该很高兴。

可复制的示例:

from pyspark.sql import SparkSession, Window
from pyspark.sql.functions import desc, dense_rank

spark = SparkSession.builder.appName('spark_session').getOrCreate()

data = [
    (100, 1, 2, 1),
    (100, 1, 1, -1),
    (200, 1, 3, 1),
    (200, 1, 3, 4)   
]

df = spark.createDataFrame(data, ("col_1", "col_2", "col_3", 'order_col'))

df.show()

# +-----+-----+-----+---------+
# |col_1|col_2|col_3|order_col|
# +-----+-----+-----+---------+
# |  100|    1|    2|        1|
# |  100|    1|    1|       -1|
# |  200|    1|    3|        1|
# |  200|    1|    3|        4|
# +-----+-----+-----+---------+

def get_recent_date(input_df, *partition_col, order_col):
    w = Window().partitionBy(*partition_col)\
    .orderBy(desc(order_col))
    output_df= input_df.withColumn('DenseRank', dense_rank().over(w))
    return output_df


new_df = get_recent_date(
    df, 'col_2', order_col='order_col'
)

new_df.show()

# +-----+-----+-----+---------+---------+
# |col_1|col_2|col_3|order_col|DenseRank|
# +-----+-----+-----+---------+---------+
# |  200|    1|    3|        4|        1|
# |  100|    1|    2|        1|        2|
# |  200|    1|    3|        1|        2|
# |  100|    1|    1|       -1|        3|
# +-----+-----+-----+---------+---------+

new_df = get_recent_date(
    df, 'col_2', 'col_1', order_col='order_col'
)

new_df.show()

# |col_1|col_2|col_3|order_col|DenseRank|
# +-----+-----+-----+---------+---------+
# |  100|    1|    2|        1|        1|
# |  100|    1|    1|       -1|        2|
# |  200|    1|    3|        4|        1|
# |  200|    1|    3|        1|        2|
# +-----+-----+-----+---------+---------+

评论

0赞 SunflowerParty 9/29/2023
这非常有效。谢谢!