Spark Equivalent of IF Then ELSE
我在这里早些时候已经看到了这个问题,并从中吸取了教训。 但是,我不确定为什么感觉应该可以工作时出现错误。
我想通过一些规则在现有Spark
1 2 3 4 5 | from pyspark.sql import functions as F iris_spark_df = iris_spark.withColumn( "Class", F.when(iris_spark.iris_class == 'Iris-setosa', 0, F.when(iris_spark.iris_class == 'Iris-versicolor',1)).otherwise(2)) |
引发以下错误。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-157-21818c7dc060> in <module>() ----> 1 iris_spark_df=iris_spark.withColumn("Class",F.when(iris_spark.iris_class=='Iris-setosa',0,F.when(iris_spark.iris_class=='Iris-versicolor',1))) TypeError: when() takes exactly 2 arguments (3 given) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-157-21818c7dc060> in <module>() ----> 1 iris_spark_df=iris_spark.withColumn("Class",F.when(iris_spark.iris_class=='Iris-setosa',0,F.when(iris_spark.iris_class=='Iris-versicolor',1))) TypeError: when() takes exactly 2 arguments (3 given) |
知道为什么吗?
正确的结构是:
1 2 3 | (when(col("iris_class") == 'Iris-setosa', 0) .when(col("iris_class") == 'Iris-versicolor', 1) .otherwise(2)) |
相当于
1 2 3 4 5 | CASE WHEN (iris_class = 'Iris-setosa') THEN 0 WHEN (iris_class = 'Iris-versicolor') THEN 1 ELSE 2 END |
要么:
1 2 3 | (when(col("iris_class") == 'Iris-setosa', 0) .otherwise(when(col("iris_class") == 'Iris-versicolor', 1) .otherwise(2))) |
等效于:
1 2 3 4 5 | CASE WHEN (iris_class = 'Iris-setosa') THEN 0 ELSE CASE WHEN (iris_class = 'Iris-versicolor') THEN 1 ELSE 2 END END |
使用一般语法:
1 | when(condition, value).when(...) |
要么
1 | when(condition, value).otherwise(...) |
您可能将Hive
1 | IF(condition, if-true, if-false) |
只能在具有Hive支持的原始SQL中使用。
Spark中的条件语句
- 在DataFrame上使用"否则"
- 在DataFrame上使用" case when"
- 使用&&和||算子
1 2 3 4 5 6 7 8 9 10 11 12 13 | import org.apache.spark.sql.functions.{when, _} import spark.sqlContext.implicits._ val spark: SparkSession = SparkSession.builder().master("local[1]").appName("SparkByExamples.com").getOrCreate() val data = List(("James","","Smith","36636","M",60000), ("Michael","Rose","","40288","M",70000), ("Robert","","Williams","42114","",400000), ("Maria","Anne","Jones","39192","F",500000), ("Jen","Mary","Brown","","F",0)) val cols = Seq("first_name","middle_name","last_name","dob","gender","salary") val df = spark.createDataFrame(data).toDF(cols:_*) |
1.在DataFrame上使用"否则"
用新的价值代替性别的价值
1 2 3 4 5 6 7 | val df1 = df.withColumn("new_gender", when(col("gender") ==="M","Male") .when(col("gender") ==="F","Female") .otherwise("Unknown")) val df2 = df.select(col("*"), when(col("gender") ==="M","Male") .when(col("gender") ==="F","Female") .otherwise("Unknown").alias("new_gender")) |
2.在DataFrame上使用" case when"
1 2 3 4 | val df3 = df.withColumn("new_gender", expr("case when gender = 'M' then 'Male'" + "when gender = 'F' then 'Female'" + "else 'Unknown' end")) |
或者,
1 2 3 4 | val df4 = df.select(col("*"), expr("case when gender = 'M' then 'Male'" + "when gender = 'F' then 'Female'" + "else 'Unknown' end").alias("new_gender")) |
3.使用&&和||算子
1 2 3 4 5 6 7 8 | val dataDF = Seq( (66,"a","4"), (67,"a","0"), (70,"b","4"), (71,"d","4" )).toDF("id","code","amt") dataDF.withColumn("new_column", when(col("code") ==="a" || col("code") ==="d","A") .when(col("code") ==="b" && col("amt") ==="4","B") .otherwise("A1")) .show() |
输出:
1 2 3 4 5 6 7 8 | +---+----+---+----------+ | id|code|amt|new_column| +---+----+---+----------+ | 66| a| 4| A| | 67| a| 0| A| | 70| b| 4| B| | 71| d| 4| A| +---+----+---+----------+ |
有多种方法可以实现if-then-else。
在DataFrame API中使用when函数。
您可以在何时指定条件列表,也可以在其他情况下指定所需的值。您也可以嵌套形式使用此表达式。
expr函数。
使用" expr"功能,您可以在expr中传递SQL表达式。 PFB示例。在这里,我们基于月份列创建新列"季度"。
1 2 3 4 5 6 7 8 9 10 | cond ="""case when month > 9 then 'Q4' else case when month > 6 then 'Q3' else case when month > 3 then 'Q2' else case when month > 0 then 'Q1' end end end end as quarter""" newdf = df.withColumn("quarter", expr(cond)) |
我们还可以使用可以采用SQL表达式的select函数的变体。 PFB示例。
1 2 3 4 5 6 7 8 9 10 | cond ="""case when month > 9 then 'Q4' else case when month > 6 then 'Q3' else case when month > 3 then 'Q2' else case when month > 0 then 'Q1' end end end end as quarter""" newdf = df.selectExpr("*", cond) |
您可以使用此:
其中exp1是条件,如果为true,则给我exp2,否则给我exp3。
现在,嵌套if-else的有趣之处是。你需要通过里面的每一个经验
1 2 | brackets {"()"} else it will raise error. |
例:
1 | if((1>2), (if (2>3), True, False), (False)) |