繁体   English   中英

Spark在Spark数据框的where子句中指定多个逻辑条件

[英]Spark specify multiple logical condition in where clause of spark dataframe

在spark scala数据帧中定义多个逻辑/关系条件时,出现如下所述的错误。 但是同样的事情在scala中工作正常

Python代码:

df2=df1.where(((col('a')==col('b')) & (abs(col('c')) <= 1))
 | ((col('a')==col('fin')) & ((col('b') <= 3) & (col('c') > 1)) & (col('d') <= 500))
 | ((col('a')==col('b')) & ((col('c') <= 15) & (col('c') > 3)) & (col('d') <= 200))
 | ((col('a')==col('b')) & ((col('c') <= 30) & (col('c') > 15)) & (col('c') <= 100)))

尝试与scala等效:

val df_aqua_xentry_dtb_match=df_aqua_xentry.where((col("a") eq col("b")) &  (abs(col("c") ) <= 1))
 notebook:2: error: type mismatch;
 found   : org.apache.spark.sql.Column
 required: Boolean
val df_aqua_xentry_dtb_match=df_aqua_xentry.where((col("a") eq col("b")) &  (abs(col("c") ) <= 1))

如何使用scala在Spark数据框中定义多个逻辑条件

请参阅以下解决方案。

df.where("StudentId == 1").explain(true)

== Parsed Logical Plan ==
'Filter ('StudentId = 1)
+- Project [_1#3 AS StudentId#7, _2#4 AS SubjectName#8, _3#5 AS Marks#9]
   +- LocalRelation [_1#3, _2#4, _3#5]

== Analyzed Logical Plan ==
StudentId: int, SubjectName: string, Marks: int
Filter (StudentId#7 = 1)
+- Project [_1#3 AS StudentId#7, _2#4 AS SubjectName#8, _3#5 AS Marks#9]
   +- LocalRelation [_1#3, _2#4, _3#5]

== Optimized Logical Plan ==
LocalRelation [StudentId#7, SubjectName#8, Marks#9]

在这里,我们使用了where子句,即使代码级别的where子句,内部优化器也将其转换为过滤器操作。

因此,我们可以将过滤器功能应用于数据帧的行,如下所示

df.filter(row => row.getString(1) == "A" && row.getInt(0) == 1).show()

Here 0 and 1 are columns of data frames. In my case schema is (StudentId(Int), SubjectName(string), Marks(Int))

eq返回一个Boolean<=返回一个Column 它们不兼容。

您可能想要这样:

df.where((col("a") === col("b")) && (abs(col("c") ) <= 1))

===用于列之间的相等性并返回Column ,在那里我们可以使用&&在同一位置执行多个条件。

使用Spark您应该使用

  • ===而不是==eq (请参阅说明
  • &&代替&&&是逻辑AND, &是二进制AND)
val df_aqua_xentry_dtb_match = df_aqua_xentry.where((col("a") === col("b")) &&  (abs(col("c") ) <= 1))

Scala版本的代码几乎没有问题。

  1. “ eq”基本上是比较Scala中的两个字符串(在Java中等于==的减数),因此当您尝试使用“ eq”比较两个Columns时,它将返回一个布尔值而不是Column类型。 在这里,您可以使用“ ===”运算符进行列比较。

字符串比较

    scala> "praveen" eq "praveen"
    res54: Boolean = true 

    scala> "praveen" eq "nag"
    res55: Boolean = false   

    scala> lit(1) eq lit(2)
    res56: Boolean = false  

    scala> lit(1) eq lit(1)
    res57: Boolean = false

列比较

    scala> lit(1) === lit(2)
    res58: org.apache.spark.sql.Column = (1 = 2)

    scala> lit(1) === lit(1)
    19/08/02 14:00:40 WARN Column: Constructing trivially true equals predicate, '1 = 1'. Perhaps you need to use aliases.
    res59: org.apache.spark.sql.Column = (1 = 1)
  1. 您正在使用“ betwise AND”运算符,而不是“ and” /“ &&&”运算符作为列类型。 这就是您收到上述错误的原因(因为它期望使用布尔值而不是Column)。

      scala> df.show +---+---+ | id|id1| +---+---+ | 1| 2| +---+---+ scala> df.where((col("id") === col("id1")) && (abs(col("id")) > 2)).show +---+---+ | id|id1| +---+---+ +---+---+ scala> df.where((col("id") === col("id1")) and (abs(col("id")) > 2)).show +---+---+ | id|id1| +---+---+ +---+---+ 

希望这可以帮助 !

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM