Pyspark 具有countDistinct的倾斜数据

Pyspark 具有countDistinct的倾斜数据,pyspark,skew,Pyspark,Skew,我有一个PySpark数据框架,有3列:“客户”、“产品”、“日期”。我想运行groupBy操作: df.groupBy("product", "date").agg(F.countDistinct("client")) 所以我想统计一下每天购买产品的客户数量。这导致了数据的巨大倾斜(事实上,由于内存的原因,它会导致错误)。我一直在学习腌制技术。据我所知,它可以与“sum”或“count”一起使用,向groupBy添加一个新列并执行第

我有一个PySpark数据框架,有3列:“客户”、“产品”、“日期”。我想运行groupBy操作:

df.groupBy("product", "date").agg(F.countDistinct("client"))
所以我想统计一下每天购买产品的客户数量。这导致了数据的巨大倾斜(事实上,由于内存的原因,它会导致错误)。我一直在学习腌制技术。据我所知,它可以与“sum”或“count”一起使用,向groupBy添加一个新列并执行第二次聚合,但由于使用了
countDistinct
aggregation方法,我不知道如何在这种情况下应用它们


如何在这种情况下应用它?

我建议在这里完全不要使用
countDistinct
,而是在一行中使用两个聚合来实现您想要的效果,特别是因为您的数据存在偏差。它可以如下所示:

import pyspark.sql.functions as F
new_df = (df
  .groupBy("product", "date", "client")
  .agg({}) # getting unique ("product", "date", "client") tuples
  .groupBy("product", "date")
  .agg(F.count('*').alias('clients'))
)

这里的第一个聚合确保您有一个数据帧,每个不同的(“产品”、“日期”、“客户机”)元组有一行,第二个是计算每个(“产品”、“日期”)对的客户机数量。这样,您就不必再担心歪斜,因为Spark将知道如何为您进行部分聚合(与
countDistinct
相反,后者被迫将每个(“产品”、“日期”)对对应的所有单个“客户”值发送到一个节点).

我建议不要在这里使用
countDistinct
,而是使用一行中的两个聚合来实现您想要的,尤其是因为您的数据存在偏差。它可以如下所示:

import pyspark.sql.functions as F
new_df = (df
  .groupBy("product", "date", "client")
  .agg({}) # getting unique ("product", "date", "client") tuples
  .groupBy("product", "date")
  .agg(F.count('*').alias('clients'))
)

这里的第一个聚合确保您有一个数据帧,每个不同的(“产品”、“日期”、“客户机”)元组有一行,第二个是计算每个(“产品”、“日期”)对的客户机数量。这样,您就不必再担心歪斜,因为Spark将知道为您执行部分聚合(与强制将每个(“产品”、“日期”)对对应的所有单个“客户”值发送到一个节点的
countDistinct
相反)。

日期是否包含小时和分钟?否,只有一年一个月-day@RodrigoSernaP埃雷斯,你能澄清一下我的回答是否有助于解决这个问题吗?或者,如果没有帮助的话,可以发表一些评论。日期包含小时和分钟吗?不,只有年和月-day@RodrigoSernaP埃雷斯,你能澄清一下我的回答是否有助于解决这个问题吗?如果没有帮助的话,也可以发表一些评论。