apache-spark - Spark DataFrame 基于条件的列总和

标签 apache-spark dataframe apache-spark-sql

我想计算值的部分,只有两个分区(其中 type == red 和 where type != red)

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中的普通窗口函数仅支持按整列分区,但我需要“蓝色”和“黄色”,一起识别为“非红色”类型。

有什么想法吗?

最佳答案

首先添加一列 is_red 以便更轻松地区分两组。然后,您可以groupBy这个新列并分别获取两个组的总和。

要获得分数(部分),只需将每行的值除以正确的总和,同时考虑类型是否为红色。这部分可以在 Spark 中使用 whenotherwise 来完成。

下面是执行此操作的 Scala 代码。由于使用 groupBy 时无法保证结果的顺序,因此存在 sortBy。通过排序,下面的 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)))

可以使用 drop 删除额外的 is_red 列。

关于apache-spark - Spark DataFrame 基于条件的列总和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49518632/

相关文章:

python - 使用多列索引创建 Pandas Dataframe

scala - Scala Spark 是否在所有情况下都实现了映射缩减以并行运行任务?

scala - 线性回归中的日期使用以及使用 Spark mllib 将日期转换为数字

java - Predictionio pio 构建成功,但 pio 训练错误,未找到 'name'

python - 在 pandas 中插入日期

python - 将 3 列数据框转换为矩阵

hadoop - Impala:如何查询具有不同模式的多个 Parquet 文件

postgresql - 从 postgreSQL 读取 100M 行到 Spark 并写入 parquet

输入参数为 Map 类型的 Java Spark UDF

scala - 从结构元素的嵌套数组创建一个 Spark DataFrame?