Apache Spark,将一个“CASE WHEN ... ELSE ...”计算列添加到现有的DataFrame中

时间:2015-06-11 14:20:41

标签: scala apache-spark dataframe apache-spark-sql

我正在尝试使用Scala API向现有DataFrame添加“CASE WHEN ... ELSE ...”计算列。 启动数据帧:

color
Red
Green
Blue

所需的数据帧(SQL语法:CASE WHEN color == Green THEN 1 ELSE 0 END AS bool):

color bool
Red   0
Green 1
Blue  0

我应该如何实现这个逻辑?

4 个答案:

答案 0 :(得分:54)

即将推出的SPARK 1.4.0版本(应在未来几天内发布)。您可以使用when / otherwise语法:

// Create the dataframe
val df = Seq("Red", "Green", "Blue").map(Tuple1.apply).toDF("color")

// Use when/otherwise syntax
val df1 = df.withColumn("Green_Ind", when($"color" === "Green", 1).otherwise(0))

如果您使用的是SPARK 1.3.0,则可以选择使用UDF:

// Define the UDF
val isGreen = udf((color: String) => {
  if (color == "Green") 1
  else 0
})
val df2 = df.withColumn("Green_Ind", isGreen($"color"))

答案 1 :(得分:9)

在Spark 1.5.0中:您还可以使用SQL语法expr函数

val df3 = df.withColumn("Green_Ind", expr("case when color = 'green' then 1 else 0 end"))

或plain spark-sql

df.registerTempTable("data")
val df4 = sql(""" select *, case when color = 'green' then 1 else 0 end as Green_ind from data """)

答案 2 :(得分:1)

我发现了这个:

https://issues.apache.org/jira/browse/SPARK-3813

在火花2.1.0上为我工作:

import sqlContext._
val rdd = sc.parallelize((1 to 100).map(i => Record(i, s"val_$i")))
rdd.registerTempTable("records")
println("Result of SELECT *:")
sql("SELECT case key when '93' then 'ravi' else key end FROM records").collect()

答案 3 :(得分:0)

我一直在寻找这么长时间,所以这里是SPARK 2.1 JAVA与其他java用户的分组示例。

import static org.apache.spark.sql.functions.*;
 //...
    Column uniqTrue = col("uniq").equalTo(true);
    Column uniqFalse = col("uniq").equalTo(false);

    Column testModeFalse = col("testMode").equalTo(false);
    Column testModeTrue = col("testMode").equalTo(true);

    Dataset<Row> x = basicEventDataset
            .groupBy(col(group_field))
            .agg(
                    sum(when((testModeTrue).and(uniqTrue), 1).otherwise(0)).as("tt"),
                    sum(when((testModeFalse).and(uniqTrue), 1).otherwise(0)).as("ft"),
                    sum(when((testModeTrue).and(uniqFalse), 1).otherwise(0)).as("tf"),
                    sum(when((testModeFalse).and(uniqFalse), 1).otherwise(0)).as("ff")
            );