【问题标题】:how to achieve execute several functions on each column dynamically?如何实现在每一列上动态执行多个函数?
【发布时间】:2020-01-16 12:43:56
【问题描述】:

我在 java8 中使用 spark-sql-2.4.1v。

我有以下场景

val df = Seq(
  ("0.9192019",  "0.1992019",  "0.9955999"),
  ("0.9292018",  "0.2992019",  "0.99662018"),
  ("0.9392017",  "0.3992019",  "0.99772000")).toDF("item1_value","item2_value","item3_value")
.withColumn("item1_value", $"item1_value".cast(DoubleType))
.withColumn("item2_value", $"item2_value".cast(DoubleType))
.withColumn("item3_value", $"item3_value".cast(DoubleType))

df.show(20)

我需要这样的预期输出

-----------------------------------------------------------------------------------
col_name      |  sum_of_column     | avg_of_column   | vari_of_column 
-----------------------------------------------------------------------------------
"item1_value" | sum("item1_value") | avg("item1_value") | variance("item1_value")
"item2_value" | sum("item2_value") | avg("item2_value") | variance("item2_value")
"item3_value" | sum("item3_value") | avg("item3_value") | variance("item3_value")
----------------------------------------------------------------------------------

如何动态实现这一点......明天我可能会有

【问题讨论】:

标签: apache-spark java-8 apache-spark-sql


【解决方案1】:

这是可以实现此目的的示例代码。如果需要,您可以使列列表动态化并添加更多功能。

import org.apache.spark.sql.types._
import org.apache.spark.sql.Column

val df = Seq(
  ("0.9192019",  "0.1992019",  "0.9955999"),
  ("0.9292018",  "0.2992019",  "0.99662018"),
  ("0.9392017",  "0.3992019",  "0.99772000")).
  toDF("item1_value","item2_value","item3_value").
  withColumn("item1_value", $"item1_value".cast(DoubleType)).
  withColumn("item2_value", $"item2_value".cast(DoubleType)).
  withColumn("item3_value", $"item3_value".cast(DoubleType))

val aggregateColumns = Seq("item1_value","item2_value","item3_value")

var aggDFs = aggregateColumns.map( c => {
    df.groupBy().agg(lit(c).as("col_name"),sum(c).as("sum_of_column"), avg(c).as("avg_of_column"), variance(c).as("var_of_column"))
})

var combinedDF = aggDFs.reduce(_ union _)

这将返回以下输出:

scala> df.show(10,false)
+-----------+-----------+-----------+
|item1_value|item2_value|item3_value|
+-----------+-----------+-----------+
|0.9192019  |0.1992019  |0.9955999  |
|0.9292018  |0.2992019  |0.99662018 |
|0.9392017  |0.3992019  |0.99772    |
+-----------+-----------+-----------+


scala> combinedDF.show(10,false)
+-----------+------------------+------------------+---------------------+
|col_name   |sum_of_column     |avg_of_column     |var_of_column        |
+-----------+------------------+------------------+---------------------+
|item1_value|2.7876054         |0.9292018         |9.999800000999957E-5 |
|item2_value|0.8976057000000001|0.2992019         |0.010000000000000002 |
|item3_value|2.9899400800000002|0.9966466933333334|1.1242332201333484E-6|
+-----------+------------------+------------------+---------------------+

【讨论】:

  • 当时的动态是什么?
  • @BdEngineer 这里没有针对“var”的特定内容。 aggDFs.reduce(_ union _) 正在对每列聚合的所有数据帧进行联合。
  • @BdEngineer 我无法检查 Java 中的代码,但您可以进行简单的联合。 Spark 将在运行时对其进行优化。对于 Seq 中的每一列,它只是转换阶段。当 action 被调用时,只有所有的转换发生,spark 将为每一列并行运行它们。您可以在 Spark UI - SQL 选项卡中进行验证
  • @Ramdev Sharma 你能告诉我这个广播变量访问有什么问题吗? stackoverflow.com/questions/64003697/…
猜你喜欢
  • 2019-05-15
  • 2020-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多