在Spark-Sql 1.6版中,使用DataFrame
s,是否有办法为特定列计算每行的当前行和下一行的分数?
例如,如果我有一个包含一列的表,就像这样
Age
100
50
20
4
我想要以下输出
Franction
2
2.5
5
最后一行被删除,因为它没有要添加的“下一行”。
现在我正在通过对表格进行排名并将其与自身结合来实现,其中rank
等于rank+1
。
有更好的方法吗?
可以使用Window
函数来完成吗?
答案 0 :(得分:3)
Window
函数应该只做部分技巧。其他部分技巧可以通过定义udf
函数
def div = udf((age: Double, lag: Double) => lag/age)
首先,我们需要使用lag
函数找到Window
,然后在lag
函数中传递age
和udf
来查找div
}
import sqlContext.implicits._
import org.apache.spark.sql.functions ._
val dataframe = Seq(
("A",100),
("A",50),
("A",20),
("A",4)
).toDF("person", "Age")
val windowSpec = Window.partitionBy("person").orderBy(col("Age").desc)
val newDF = dataframe.withColumn("lag", lag(dataframe("Age"), 1) over(windowSpec))
最后调用udf函数
newDF.filter(newDF("lag").isNotNull).withColumn("div", div(newDF("Age"), newDF("lag"))).drop("Age", "lag").show
最终输出将是
+------+---+
|person|div|
+------+---+
| A|2.0|
| A|2.5|
| A|5.0|
+------+---+
<强>被修改强>
由于@Jacek建议使用.na.drop
代替.filter(newDF("lag").isNotNull)
并使用/
运算符的更好解决方案,因此我们甚至不需要调用udf
函数< / p>
newDF.na.drop.withColumn("div", newDF("lag")/newDF("Age")).drop("Age", "lag").show