火花数据帧中过滤器的多个条件
multiple conditions for filter in spark data frames
我有一个包含四个字段的数据框。其中一个字段名称是 Status,我正在尝试在 .filter 中使用 OR 条件作为数据框。我尝试了以下查询,但没有成功。
df2 = df1.filter(("Status=2") || ("Status =3"))
df2 = df1.filter("Status=2" || "Status =3")
有没有人用过这个。我在堆栈溢出 上看到过类似的问题。他们使用以下代码来使用 OR 条件。但该代码适用于 pyspark。
from pyspark.sql.functions import col
numeric_filtered = df.where(
(col('LOW') != 'null') |
(col('NORMAL') != 'null') |
(col('HIGH') != 'null'))
numeric_filtered.show()
而不是:
df2 = df1.filter("Status=2" || "Status =3")
尝试:
df2 = df1.filter($"Status" === 2 || $"Status" === 3)
您需要使用过滤器
package dataframe
import org.apache.spark.sql.SparkSession
/**
* @author vaquar.khan@gmail.com
*/
//
object DataFrameExample{
//
case class Employee(id: Integer, name: String, address: String, salary: Double, state: String,zip:Integer)
//
def main(args: Array[String]) {
val spark =
SparkSession.builder()
.appName("DataFrame-Basic")
.master("local[4]")
.getOrCreate()
import spark.implicits._
// create a sequence of case class objects
// (we defined the case class above)
val emp = Seq(
Employee(1, "vaquar khan", "111 algoinquin road chicago", 120000.00, "AZ",60173),
Employee(2, "Firdos Pasha", "1300 algoinquin road chicago", 2500000.00, "IL",50112),
Employee(3, "Zidan khan", "112 apt abcd timesqure NY", 50000.00, "NY",55490),
Employee(4, "Anwars khan", "washington dc", 120000.00, "VA",33245),
Employee(5, "Deepak sharma ", "rolling edows schumburg", 990090.00, "IL",60172),
Employee(6, "afaq khan", "saeed colony Bhopal", 1000000.00, "AZ",60173)
)
val employee=spark.sparkContext.parallelize(emp, 4).toDF()
employee.printSchema()
employee.show()
employee.select("state", "zip").show()
println("*** use filter() to choose rows")
employee.filter($"state".equalTo("IL")).show()
println("*** multi contidtion in filer || ")
employee.filter($"state".equalTo("IL") || $"state".equalTo("AZ")).show()
println("*** multi contidtion in filer && ")
employee.filter($"state".equalTo("AZ") && $"zip".equalTo("60173")).show()
}
}
这个问题已经回答了,但是为了将来参考,我想提一下,在这个问题的上下文中,Dataset/Dataframe中的where
和filter
方法支持两个语法:
SQL 字符串参数:
df2 = df1.filter(("Status = 2 or Status = 3"))
和基于 Col 的参数(由 提到):
df2 = df1.filter($"Status" === 2 || $"Status" === 3)
OP 似乎结合了这两种语法。
就个人而言,我更喜欢第一种语法,因为它更简洁、更通用。
在 spark/scala 中,使用可变参数进行过滤非常容易。
val d = spark.read...//data contains column named matid
val ids = Seq("BNBEL0608AH", "BNBEL00608H")
val filtered = d.filter($"matid".isin(ids:_*))
在java spark数据集中,它可以用作
Dataset userfilter =
user.filter(col("gender").isin("male","female"));
df2 = df1.filter("Status=2")
.filter("Status=3");
df2 = df1.filter("Status = 2 OR Status = 3")
对我有用。
另一种方法是将函数 expr 与 where 子句一起使用
import org.apache.spark.sql.functions.expr
df2 = df1.where(expr("col1 = 'value1' and col2 = 'value2'"))
效果一样。
您可以尝试,(使用一个对象过滤,例如列表或一组值)
ds = ds.filter(functions.col(COL_NAME).isin(myList));
或者按照@Tony Fraser 的建议,您可以尝试,(使用对象序列)
ds = ds.filter(functions.col(COL_NAME).isin(mySeq));
所有的答案都是正确的,但其中大部分并不代表良好的编码风格。此外,您应该始终考虑未来参数的可变长度,即使它们在某个时间点是静态的。
供将来参考:
我们可以使用 isInCollection
来过滤,这里是一个例子:
注意:它将查找 完全匹配
def getSelectedTablesRows(allTablesInfoDF: DataFrame, tableNames: Seq[String]): DataFrame = {
allTablesInfoDF.where(col("table_name").isInCollection(tableNames))
}
如果我们想要 部分匹配 就像 contains 一样,我们可以像这样链接 contain 调用:
def getSelectedTablesRows2(allTablesInfoDF: DataFrame, tableNames: Seq[String]): DataFrame = {
val tableFilters = tableNames.map(_.toLowerCase()).map(name => lower(col("table_name")).contains(name))
val finalFilter = tableFilters.fold(lit(false))((accu, newTableFilter) => accu or newTableFilter)
allTablesInfoDF.where(finalFilter)
}
我有一个包含四个字段的数据框。其中一个字段名称是 Status,我正在尝试在 .filter 中使用 OR 条件作为数据框。我尝试了以下查询,但没有成功。
df2 = df1.filter(("Status=2") || ("Status =3"))
df2 = df1.filter("Status=2" || "Status =3")
有没有人用过这个。我在堆栈溢出
from pyspark.sql.functions import col
numeric_filtered = df.where(
(col('LOW') != 'null') |
(col('NORMAL') != 'null') |
(col('HIGH') != 'null'))
numeric_filtered.show()
而不是:
df2 = df1.filter("Status=2" || "Status =3")
尝试:
df2 = df1.filter($"Status" === 2 || $"Status" === 3)
您需要使用过滤器
package dataframe
import org.apache.spark.sql.SparkSession
/**
* @author vaquar.khan@gmail.com
*/
//
object DataFrameExample{
//
case class Employee(id: Integer, name: String, address: String, salary: Double, state: String,zip:Integer)
//
def main(args: Array[String]) {
val spark =
SparkSession.builder()
.appName("DataFrame-Basic")
.master("local[4]")
.getOrCreate()
import spark.implicits._
// create a sequence of case class objects
// (we defined the case class above)
val emp = Seq(
Employee(1, "vaquar khan", "111 algoinquin road chicago", 120000.00, "AZ",60173),
Employee(2, "Firdos Pasha", "1300 algoinquin road chicago", 2500000.00, "IL",50112),
Employee(3, "Zidan khan", "112 apt abcd timesqure NY", 50000.00, "NY",55490),
Employee(4, "Anwars khan", "washington dc", 120000.00, "VA",33245),
Employee(5, "Deepak sharma ", "rolling edows schumburg", 990090.00, "IL",60172),
Employee(6, "afaq khan", "saeed colony Bhopal", 1000000.00, "AZ",60173)
)
val employee=spark.sparkContext.parallelize(emp, 4).toDF()
employee.printSchema()
employee.show()
employee.select("state", "zip").show()
println("*** use filter() to choose rows")
employee.filter($"state".equalTo("IL")).show()
println("*** multi contidtion in filer || ")
employee.filter($"state".equalTo("IL") || $"state".equalTo("AZ")).show()
println("*** multi contidtion in filer && ")
employee.filter($"state".equalTo("AZ") && $"zip".equalTo("60173")).show()
}
}
这个问题已经回答了,但是为了将来参考,我想提一下,在这个问题的上下文中,Dataset/Dataframe中的where
和filter
方法支持两个语法:
SQL 字符串参数:
df2 = df1.filter(("Status = 2 or Status = 3"))
和基于 Col 的参数(由
df2 = df1.filter($"Status" === 2 || $"Status" === 3)
OP 似乎结合了这两种语法。 就个人而言,我更喜欢第一种语法,因为它更简洁、更通用。
在 spark/scala 中,使用可变参数进行过滤非常容易。
val d = spark.read...//data contains column named matid
val ids = Seq("BNBEL0608AH", "BNBEL00608H")
val filtered = d.filter($"matid".isin(ids:_*))
在java spark数据集中,它可以用作
Dataset userfilter = user.filter(col("gender").isin("male","female"));
df2 = df1.filter("Status=2")
.filter("Status=3");
df2 = df1.filter("Status = 2 OR Status = 3")
对我有用。
另一种方法是将函数 expr 与 where 子句一起使用
import org.apache.spark.sql.functions.expr
df2 = df1.where(expr("col1 = 'value1' and col2 = 'value2'"))
效果一样。
您可以尝试,(使用一个对象过滤,例如列表或一组值)
ds = ds.filter(functions.col(COL_NAME).isin(myList));
或者按照@Tony Fraser 的建议,您可以尝试,(使用对象序列)
ds = ds.filter(functions.col(COL_NAME).isin(mySeq));
所有的答案都是正确的,但其中大部分并不代表良好的编码风格。此外,您应该始终考虑未来参数的可变长度,即使它们在某个时间点是静态的。
供将来参考:
我们可以使用 isInCollection
来过滤,这里是一个例子:
注意:它将查找 完全匹配
def getSelectedTablesRows(allTablesInfoDF: DataFrame, tableNames: Seq[String]): DataFrame = {
allTablesInfoDF.where(col("table_name").isInCollection(tableNames))
}
如果我们想要 部分匹配 就像 contains 一样,我们可以像这样链接 contain 调用:
def getSelectedTablesRows2(allTablesInfoDF: DataFrame, tableNames: Seq[String]): DataFrame = {
val tableFilters = tableNames.map(_.toLowerCase()).map(name => lower(col("table_name")).contains(name))
val finalFilter = tableFilters.fold(lit(false))((accu, newTableFilter) => accu or newTableFilter)
allTablesInfoDF.where(finalFilter)
}