假设我有一个如下的数据框:
在这里,您可以看到事务编号1,2和3对于列A,B,C具有相同的值,但对于列D和E具有不同的值。列E具有日期条目。
所以最终输出将是(3和5)或(4和5)。
现在应该如何处理:
reduceByKey和groupByKey都可以用于相同的目的但是 reduceByKey在大型数据集上运行得更好。那是因为Spark 知道它可以将输出与每个分区上的公共密钥组合起来 洗牌数据。
解决此问题的最佳方法是什么?提前致谢。
编辑:我需要取回已过滤的交易。怎么做呢?
答案 0 :(得分:0)
可通过几个步骤进行链接。 Agregated Dataframe:
val agregatedDF=initialDF.select("A","B","C","E").groupBy("A","B","C").agg(max("E").as("E_max"))
链接intial-agregated:
initialDF.join(agregatedDF, List("A","B","C"))
如果初始DataFrame来自Hive,则所有内容都可以简化。
答案 1 :(得分:0)
val initialDF = Seq((1,1,1,1,"2/28/2017 0:00"),(1,1,1,2,"3/1/2017 0:00"),
(1,1,1,3,"3/1/2017 0:00"),(2,2,2,1,"2/28/2017 0:00"),(2,2,2,2,"2/25/20170:00"))
这将错过相应的col(D)
initialDF
.toDS.groupBy("_1","_2","_3")
.agg(max(col("_5"))).show
如果您想要max col的相应colD:
initialDF.toDS.map(x=>x._1,x._2,x._3,x._5,x._4))).groupBy("_1","_2","_3")
.agg(max(col("_4")).as("_4")).select(col("_1"),col("_2"),col("_3"),col("_4._2"),col("_4._1")).show
对于ReduceByKey,您可以将数据集转换为pairRDD然后解决它。如果Catalyst无法在第一个中优化groupByKey,应该更快。请参阅Rolling your own reduceByKey in Spark Dataset
答案 2 :(得分:0)
我使用spark window functions来获取解决方案:
val window = Window
.partitionBy(dataframe("A"), dataframe("B"),dataframe("C"))
.orderBy(dataframe("E") desc)
val dfWithRowNumber = dataframe.withColumn("row_number", row_number() over window)
val filteredDf = dfWithRowNumber.filter(dfWithRowNumber("row_number") === 1)