gpt4 book ai didi

scala - 根据spark中前一行同一列的值计算值

转载 作者:行者123 更新时间:2023-12-04 15:38:25 25 4
gpt4 key购买 nike

我有一个问题,我必须使用一个公式来计算列,该公式使用在前一行中完成的计算的值。

我无法使用 withColumn API 解决这个问题。

我需要使用以下公式计算一个新列:

MovingRate = MonthlyRate + (0.7 * MovingRatePrevious)

... 其中 MovingRatePrevious 是前一行的 MovingRate

对于第 1 个月,我有值,所以我不需要重新计算它,但我需要该值才能计算后续行。我需要按类型进行分区。

这是我的原始数据集:

enter image description here

MovingRate 列中的所需结果:

enter image description here

最佳答案

尽管它可能与 Widow 函数有关(请参阅@Leo C 的回答),但我敢打赌,使用 groupBy 对每个 Type 聚合一次会更高效。然后,展开 UDF 的结果以取回所有行:

val df = Seq(
(1, "blue", 0.4, Some(0.33)),
(2, "blue", 0.3, None),
(3, "blue", 0.7, None),
(4, "blue", 0.9, None)
)
.toDF("Month", "Type", "MonthlyRate", "MovingRate")

// this udf produces an Seq of Tuple3 (Month, MonthlyRate, MovingRate)
val calcMovingRate = udf((startRate:Double,rates:Seq[Row]) => rates.tail
.scanLeft((rates.head.getInt(0),startRate,startRate))((acc,curr) => (curr.getInt(0),curr.getDouble(1),acc._3+0.7*curr.getDouble(1)))
)

df
.groupBy($"Type")
.agg(
first($"MovingRate",ignoreNulls=true).as("startRate"),
collect_list(struct($"Month",$"MonthlyRate")).as("rates")
)
.select($"Type",explode(calcMovingRate($"startRate",$"rates")).as("movingRates"))
.select($"Type",$"movingRates._1".as("Month"),$"movingRates._2".as("MonthlyRate"),$"movingRates._3".as("MovingRate"))
.show()

给出:

+----+-----+-----------+------------------+
|Type|Month|MonthlyRate| MovingRate|
+----+-----+-----------+------------------+
|blue| 1| 0.33| 0.33|
|blue| 2| 0.3| 0.54|
|blue| 3| 0.7| 1.03|
|blue| 4| 0.9|1.6600000000000001|
+----+-----+-----------+------------------+

关于scala - 根据spark中前一行同一列的值计算值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58959703/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com