说明
给定一个Dataframe df
```
id | date
1 | 2015-09-01
2 | 2015-09-01
1 | 2015-09-03
1 | 2015-09-04
2 | 2015-09-04
我想创建一个运行计数器或索引,
按相同的id和
按组中的日期排序,
因此
id | date | counter
1 | 2015-09-01 | 1
1 | 2015-09-03 | 2
1 | 2015-09-04 | 3
2 | 2015-09-01 | 1
2 | 2015-09-04 | 2
这是我可以通过窗口功能实现的。
val w = Window.partitionBy("id").orderBy("date")
val resultDF = df.select( df("id"), rowNumber().over(w) )
不幸的是,spark 1.4.1不支持常规Dataframe的窗口函数:
org.apache.spark.sql.AnalysisException: Could not resolve window function 'row_number'. Note that, using window functions currently requires a HiveContext;
## 问题
如何在不使用窗口函数的情况下在CurrentSpark 1.4.1上实现上述计算?
spark何时支持常规Dataframe的窗口功能?
谢谢!
3条答案
按热度按时间bcs8qyzn1#
你可以用RDD做这个。就我个人而言,我发现RDD的api更有意义——我并不总是希望我的数据像Dataframe一样“扁平”。
上述结果如下:
如果你想在“组”内的位置,你可以使用
zipWithIndex
.你可以把它放回一个简单的列表/数组
Row
对象,但如果您需要在“组”上执行任何操作,这将不是一个好主意。像这样使用rdd的缺点是,从Dataframe到rdd再到rdd的转换非常繁琐。
hiz5n14c2#
你可以用
HiveContext
对于本地DataFrames
另外,除非你有很好的理由不这样做,否则这可能是个好主意。这是默认值SQLContext
提供于spark-shell
以及pyspark
壳牌(就目前而言)sparkR
似乎用的是普通的SQLContext
)其解析器由sparksql和dataframe指南推荐。hs1ihplo3#
我完全同意,如果您有spark版本(>=)1.5,那么dataframes的窗口函数就是一个不错的选择。但是如果你真的被旧版本(例如1.4.1)困住了,这里有一个黑客的方法来解决这个问题
现在如果你这么做了
dfWithCounter.show
您将获得:请注意
date
不是排序,而是counter
是正确的。您还可以更改counter
通过改变<=
至>=
在where
声明。