根据日期过滤火花数据帧

Ste*_*eve 21 apache-spark apache-spark-sql

我有一个数据帧

date, string, string
Run Code Online (Sandbox Code Playgroud)

我想在某段时间之前选择日期.我试过以下没有运气

 data.filter(data("date") < new java.sql.Date(format.parse("2015-03-14").getTime))
Run Code Online (Sandbox Code Playgroud)

我收到一条错误说明以下内容

org.apache.spark.sql.AnalysisException: resolved attribute(s) date#75 missing from date#72,uid#73,iid#74 in operator !Filter (date#75 < 16508);
Run Code Online (Sandbox Code Playgroud)

据我所知,查询不正确.任何人都可以告诉我应该格式化查询的方式?

我检查了数据框中的所有企业都有价值 - 他们这样做了.

eli*_*sah 47

火花1.5以来,以下解决方案适用:

低于:

// filter data where the date is lesser than 2015-03-14
data.filter(data("date").lt(lit("2015-03-14")))      
Run Code Online (Sandbox Code Playgroud)

大于:

// filter data where the date is greater than 2015-03-14
data.filter(data("date").gt(lit("2015-03-14"))) 
Run Code Online (Sandbox Code Playgroud)

为了平等,您可以使用equalTo===:

data.filter(data("date") === lit("2015-03-14"))
Run Code Online (Sandbox Code Playgroud)

如果您的DataFrame日期列是类型StringType,您可以使用以下to_date函数进行转换:

// filter data where the date is greater than 2015-03-14
data.filter(to_date(data("date")).gt(lit("2015-03-14"))) 
Run Code Online (Sandbox Code Playgroud)

您还可以使用以下year功能按年份过滤:

// filter data where year is greater or equal to 2016
data.filter(year($"date").geq(lit(2016))) 
Run Code Online (Sandbox Code Playgroud)


Ruu*_*Pul 14

不要按照其他答案中的建议使用它

.filter(f.col("dateColumn") < f.lit('2017-11-01'))
Run Code Online (Sandbox Code Playgroud)

但是用这个代替

.filter(f.col("dateColumn") < f.unix_timestamp(f.lit('2017-11-01 00:00:00')).cast('timestamp'))
Run Code Online (Sandbox Code Playgroud)

这将使用TimestampType代替StringType,这在某些情况下会更高效。例如 Parquet 谓词下推仅适用于后者。


Pra*_*upu 7

在 PySpark(python) 中,选项之一是将列设为 unix_timestamp 格式。我们可以将字符串转换为 unix_timestamp 并指定如下所示的格式。注意我们需要导入 unix_timestamp 和 lit 函数

from pyspark.sql.functions import unix_timestamp, lit

df.withColumn("tx_date", to_date(unix_timestamp(df_cast["date"], "MM/dd/yyyy").cast("timestamp")))
Run Code Online (Sandbox Code Playgroud)

现在我们可以应用过滤器

df_cast.filter(df_cast["tx_date"] >= lit('2017-01-01')) \
       .filter(df_cast["tx_date"] <= lit('2017-01-31')).show()
Run Code Online (Sandbox Code Playgroud)


Rob*_*inL 7

我发现表达这一点的最易读的方法是使用 sql 表达式:

df.filter("my_date < date'2015-01-01'")
Run Code Online (Sandbox Code Playgroud)

我们可以通过查看物理计划来验证这是否正确 .explain()

+- *(1) Filter (isnotnull(my_date#22) && (my_date#22 < 16436))
Run Code Online (Sandbox Code Playgroud)