我正在尝试获取数据集中的前n项。
最初我这样做了。
var df = Seq( (1 , "row1") , (2,"row2"), (1,"row11") , (1 , null) ).toDF()
df=df.select($"_1".alias("p_int"), $"_2".alias("p_string"))
val resultDf =df.where($"p_string".isNotNull).select( $"p_int" ,$"p_int" +1 , upper($"p_string") , rank().over(Window.partitionBy($"p_int").orderBy( $"p_string" )) as "RANKINDEX", row_number().over(Window.partitionBy($"p_int").orderBy( $"p_string" )) as "ROWNUMBER" ).where($"ROWNUMBER" <= 2 )
但我想避免操作的性能成本“where($”ROWNUMBER“&lt; = 10)”
所以我决定做以下
var df = Seq( (1 , "row1") , (2,"row2"), (1,"row11") , (1 , null) ).toDF()
df=df.select($"_1".alias("p_int"), $"_2".alias("p_string"))
val test =df.where($"p_string".isNotNull).select( $"p_int" ,$"p_int" +1 , upper($"p_string") , rank().over(Window.partitionBy($"p_int").orderBy( $"p_string" )) as "RANKINDEX", row_number().over(Window.partitionBy($"p_int").orderBy( $"p_string" )) as "ROWNUMBER" )
implicit val encoder = RowEncoder(test.schema)
var temp =test.mapPartitions( _.take(2))
但是,我的测试似乎表明这不会产生正确的输出。
任何想法为什么。从窗口数据集获取的迭代器上的take函数不会获得迭代器中的前n个元素吗?
答案 0 :(得分:0)
Dataset
的分区与PARTITION BY
子句一一对应。 OVER (PARTITION BY ...)
中的所有魔法都发生在更低的级别上,单个物理分区将处理多个ID。
你也不能真正挽救这项工作。要正确生成row_numbers
,Spark必须对所有数据进行随机排序,排序和扫描。您需要更低级别的机制来避免完全混乱和排序(例如Aggregator
使用二进制堆)。