我想计算值的一部分,只有两个分区(类型==红色,类型!=红色)
ID | type | value
-----------------------------
1 | red | 10
2 | blue | 20
3 | yellow | 30
结果应该是:
ID | type | value | portion
-----------------------------
1 | red | 10 | 1
2 | blue | 20 |0.4
3 | yellow | 30 |0.6
spark中的常规窗口功能仅支持按整个列进行分区,但是我需要“ blue”和“ yellow”,它们一起被识别为“ non-red”类型。
任何的想法?
首先添加一列is_red
,以便于区分两组。然后,您可以在groupBy
此新列中分别获取两组的总和。
要获得分数(部分),只需将每行的值除以正确的总和,并考虑类型是否为红色。这部分可以使用when
和otherwise
在Spark中完成。
下面是执行此操作的Scala代码。有一个sortBy
使用时,因为groupBy
结果的顺序无法得到保证。通过排序,sum1
下面将包含所有非红色类型sum2
的总和,而红色则是红色的总和。
val sum1 :: sum2 :: _ = df.withColumn("is_red", $"type" === lit("red"))
.groupBy($"is_red")
.agg(sum($"value"))
.collect()
.map(row => (row.getAs[Boolean](0), row.getAs[Long](1)))
.toList
.sortBy(_._1)
.map(_._2)
val df2 = df.withColumn("portion", when($"is_red", $"value"/lit(sum2)).otherwise($"value"/lit(sum1)))
is_red
可以使用删除多余的列drop
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句