Apache spark 性能:按先前分组列的子集分组
我有一个带有两个分类列的数据框架,类似于以下示例:Apache spark 性能:按先前分组列的子集分组,apache-spark,dataframe,apache-spark-sql,Apache Spark,Dataframe,Apache Spark Sql,我有一个带有两个分类列的数据框架,类似于以下示例: +----+-------+-------+ | ID | Cat A | Cat B | +----+-------+-------+ | 1 | A | B | | 2 | B | C | | 5 | A | B | | 7 | B | C | | 8 | A | C | +----+-------+-------+ 我需要做一些处理,这需要两个步骤
+----+-------+-------+
| ID | Cat A | Cat B |
+----+-------+-------+
| 1 | A | B |
| 2 | B | C |
| 5 | A | B |
| 7 | B | C |
| 8 | A | C |
+----+-------+-------+
我需要做一些处理,这需要两个步骤:第一个步骤需要将数据按两个分类列分组。在本例中,它将生成以下数据帧:
+-------+-------+-----+
| Cat A | Cat B | Cnt |
+-------+-------+-----+
| A | B | 2 |
| B | C | 2 |
| A | C | 1 |
+-------+-------+-----+
然后,下一步包括仅按CatA分组,以计算新的聚合,例如:
+-----+-----+
| Cat | Cnt |
+-----+-----+
| A | 3 |
| B | 2 |
+-----+-----+
现在是问题:
val df2=df.groupBy(“catA”、“catB”).agg(…)
然后我将这个df2
进行聚合,得到最后一个:
val df3=df2.groupBy(“catA”).agg(…)
我认为它比再次聚合第一个DF更有效。这是一个好的假设吗?还是没什么区别一般来说,它看起来是一种很好的方法,应该比两次聚合数据更有效。由于洗牌文件是隐式缓存的,所以至少部分工作应该只执行一次。因此,当您在
df2
上调用操作,然后在df3
上调用操作时,您应该会看到与df2
对应的阶段已被跳过。此外,在第二次agg
期间,由第一次洗牌强制执行的部分结构可能会减少聚合缓冲区的内存需求
不幸的是,
DataFrame
聚合与RDD聚合不同,不能使用自定义分区器。这意味着您不能基于catA
的值使用一次洗牌来计算两个数据帧。这意味着第二次聚合将需要单独的exchange哈希分区。我怀疑切换到RDD是否合理一般来说,这看起来是一个好方法,应该比两次聚合数据更有效。由于洗牌文件是隐式缓存的,所以至少部分工作应该只执行一次。因此,当您在df2
上调用操作,然后在df3
上调用操作时,您应该会看到与df2
对应的阶段已被跳过。此外,在第二次agg
期间,由第一次洗牌强制执行的部分结构可能会减少聚合缓冲区的内存需求
不幸的是,DataFrame
聚合与RDD聚合不同,不能使用自定义分区器。这意味着您不能基于catA
的值使用一次洗牌来计算两个数据帧。这意味着第二次聚合将需要单独的exchange哈希分区。我怀疑它是否有理由切换到RDDs