Pyspark在每个窗口内有效地创建图案

s5a0g9ez  于 2022-11-01  发布在  Spark
关注(0)|答案(1)|浏览(99)

我想从现有的 Dataframe 中创建一个基本 Dataframe ,它并不包含我想要的所有内容,例如,我有一个 Dataframe ,收集每个人(通过“id”跟踪)每年每月购买的糖果数量(但在本例中,每个人并不是每个月都购买糖果)

|id|year_month|num_of_candies_bought
  1  2022-01           5
  1  2022-03          10
  1  2022-04           2

我想要的是,通过固定我感兴趣的年-月来跟踪他们,就像这样(今年的前5个月)

|id|year_month|num_of_candies_bought
  1  2022-01           5
  1  2022-02           0
  1  2022-03          10
  1  2022-04           2
  1  2022-05           0

我认为一种方法是使用“crossjoin”,但事实证明这需要很长的时间来处理。有没有什么方法可以在没有任何连接的情况下完成此操作?在我的工作中,第一个 Dataframe 非常非常大(例如一百万行),而第二个是固定的(就像在这个例子中只有5行)并且要小得多。有没有可能(如果需要使用交叉连接)大幅提高性能?
我想用这个把每个人分开(所以我需要用window.partition的东西)

kxeu7u2r

kxeu7u2r1#

我只需为每个id和year_month添加一个0(零)行。
让我们假设df是您的 Dataframe 。

from pyspark.sql import functions as F

# generate a list of all year_month you need

year_month = ["2022-01","2022-02","2022-03","2022-04","2022-05"]

df_id = (
    df.select("id")
    .distinct()
    .withColumn("year_month", F.lit(year_month))
    .withColumn("num_of_candies_bought", F.lit(0))
    .withColumn("year_month", F.explode("year_month"))
)

df = (
    df.unionByName(df_id)
    .groupBy("id", "year_month")
    .agg(F.sum("num_of_candies_bought").alias("num_of_candies_bought"))
)

相关问题