PySpark-一种计算常见元素的更有效方法

时间:2018-12-17 12:28:18

标签: apache-spark pyspark apache-spark-sql pyspark-sql

我有两个数据帧,例如dfAdfB
我想乘以他们的交集,然后计算该交集中唯一user_ids的数量。

我尝试了以下非常慢并且会崩溃的事情:

dfA.join(broadcast(dfB), ['user_id'], how='inner').select('user_id').dropDuplicates().count()

我需要运行许多这样的行才能获得绘图。

如何有效地执行此类查询?

2 个答案:

答案 0 :(得分:1)

如问题中所述,数据框的唯一相关部分是列user_id(在您的问题中,您描述自己加入了user_id,之后仅使用了user_id字段)

当您只需要在每个数据框中的一列的不同值时,性能问题的根源就是将两个大数据框连接起来。

为了提高性能,我将执行以下操作:

  1. 创建两个小的DF,它们仅保存每个数据帧的user_id
    这将大大减少每个数据框的大小,因为它仅包含一列(唯一相关的列)

    dfAuserid = dfA.select("user_id")
    dfBuserid = dfB.select("user_id")
    
  2. 获取distinct(注意:它等效于每个数据帧的dropDuplicate()
    这将大大减少每个数据框的大小,因为每个新数据框将仅保留列user_id的不同值。

    dfAuseridDist = dfA.select("user_id").distinct()
    dfBuseridDist = dfB.select("user_id").distinct()
    
  3. 对上述两个极简数据框执行join,以获取交点中的唯一值

答案 1 :(得分:1)

我认为您可以先选择必要的列,然后再执行连接。同样,将dropDuplicates移到联接之前也应该是有益的,因为这样可以避免在一个数据帧中多次出现的user_id。

结果查询如下:

dfA.select("user_id").join(broadcast(dfB.select("user_id")), ['user_id'], how='inner')\
    .select('user_id').dropDuplicates().count()

OR:

dfA.select("user_id").dropDuplicates(["user_id",]).join(broadcast(dfB.select("user_id")\
    .dropDuplicates(["user_id",])), ['user_id'], how='inner').select('user_id').count()

或具有不同版本的版本也应该工作。

dfA.select("user_id").distinct().join(broadcast(dfB.select("user_id").distinct()),\
    ['user_id'], how='inner').select('user_id').count()