PySpark:when 子句中的多个条件



我想修改当前为空白的数据帧列(年龄)的单元格值,并且只有在另一列(幸存)的相应行的值为 0 时,我才会这样做年龄。如果它在"幸存"列中为 1,但在"年龄"列中为空白,那么我将将其保留为空。

我尝试使用&&运算符,但它不起作用。这是我的代码:

tdata.withColumn("Age",  when((tdata.Age == "" && tdata.Survived == "0"), mean_age_0).otherwise(tdata.Age)).show()

有什么建议如何处理吗?谢谢。

错误信息:

SyntaxError: invalid syntax
  File "<ipython-input-33-3e691784411c>", line 1
    tdata.withColumn("Age",  when((tdata.Age == "" && tdata.Survived == "0"), mean_age_0).otherwise(tdata.Age)).show()
                                                    ^

你会得到SyntaxError错误异常,因为 Python 没有&&运算符。它有and&其中后者是在Column上创建布尔表达式的正确选择(|用于逻辑析取,~用于逻辑否定)。

您创建的条件也是无效的,因为它不考虑运算符优先级。 Python 中的&== 具有更高的优先级,因此表达式必须用括号括起来。

(col("Age") == "") & (col("Survived") == "0")
## Column<b'((Age = ) AND (Survived = 0))'>

附带说明一下when函数等效于case表达式而不是WHEN子句。仍然适用相同的规则。连接:

df.where((col("foo") > 0) & (col("bar") < 0))

分离:

df.where((col("foo") > 0) | (col("bar") < 0))

当然,您可以单独定义条件以避免括号:

cond1 = col("Age") == "" 
cond2 = col("Survived") == "0"
cond1 & cond2

pyspark 中时,可以使用 &(for and) 和 | (for or) 构建多个条件。

注意:在 pyspark 中,重要的是将括号 () 中的每个表达式括起来,这些表达式组合在一起形成条件

%pyspark
dataDF = spark.createDataFrame([(66, "a", "4"), 
                                (67, "a", "0"), 
                                (70, "b", "4"), 
                                (71, "d", "4")],
                                ("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()

在Spark Scala中,代码(&&)或(||)条件可以在函数中使用

//scala
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()

====

===================
Output:
+---+----+---+----------+
| id|code|amt|new_column|
+---+----+---+----------+
| 66|   a|  4|         A|
| 67|   a|  0|         A|
| 70|   b|  4|         B|
| 71|   d|  4|         A|
+---+----+---+----------+

此代码片段是从 sparkbyexamples.com

它应该至少在 pyspark 2.4 中工作

tdata = tdata.withColumn("Age",  when((tdata.Age == "") & (tdata.Survived == "0") , "NewValue").otherwise(tdata.Age))

还要确保条件的顺序也很重要。

右:限制条件是在宽松的编码之后。

ultimate_optimized_join = spark_filteredfinal_df1.crossJoin(spark_filteredfinal_df2) 
                        .where( (F.col("df1_sorted_row_num") < F.col("df2_sorted_row_num"))                                                          
                                &
                                (F.col("df1_a_x_dup") == F.col("df2_a_x_dup"))
                                ) 
                        .select(["df1_a_x_dup", "df2_a_x_dup", "df1_sorted_row_num", "df1_sorted_row_num",  "df1_collectedIds", "df2_collectedIds"])

错误:限制性条件,其中子句在宽松条件之前。

ultimate_optimized_join = spark_filteredfinal_df1.crossJoin(spark_filteredfinal_df2) 
                        .where( (F.col("df1_a_x_dup") == F.col("df2_a_x_dup"))
                                &
                                (F.col("df1_sorted_row_num") < F.col("df2_sorted_row_num"))
                                ) 
                        .select(["df1_a_x_dup", "df2_a_x_dup", "df1_sorted_row_num", "df1_sorted_row_num",  "df1_collectedIds", "df2_collectedIds"])

它应该是:

$when(((tdata.Age == "" ) & (tdata.Survived == "0")), mean_age_0)

相关内容

  • 没有找到相关文章

最新更新