我有一个带有时间戳类型列的PySpark(2.3.0)数据框:
>> df.show()
+-------------------+
| column |
+-------------------+
|2004-02-16 12:01:37|
|2004-02-23 10:28:49|
|2004-02-23 12:49:14|
|2004-02-26 12:29:58|
|2004-03-02 10:10:28|
|2004-03-03 03:40:13|
|2004-03-16 05:00:10|
|2004-03-16 03:28:21|
|2004-03-17 02:45:22|
|2004-03-23 08:14:47|
+-------------------+
>> df.printSchema()
root
|-- column: timestamp (nullable = true)
我想过滤该数据帧以查找特定日期的记录:
import datetime
date = datetime.datetime.strptime('2018-06-07', '%Y-%m-%d').date()
进行此过滤的最有效方法是什么? 注意:数据通过JDBC读入,因此可能无法分发。
这是我尝试过的(没有发现重大差异),哪个更好?我错过了什么吗?
方法1:投放日期
df.filter(psf.col('column').cast('date') == date)
方法2:匹配年,月,日等
import pyspark.sql.functions as psf
(
df
.filter(psf.dayofmonth('column') == date.day)
.filter(psf.month('column') == date.month)
.filter(psf.year('column') == date.year)
)
答案 0 :(得分:2)
这是我尝试过的(没有发现重大差异),哪个更好?
都不是。这两种方法效率低下,无法充分利用数据库和Spark功能。由于column
似乎是datetime
或等效,并且查询需要casting
,因此Spark无法下推谓词,并且在群集端应用过滤,因此性能将类似(给予或采取开销)几个函数调用。)
要提高性能,您可以按如下方式重新定义查询(加上您通常使用的其他参数):
df = spark.read.jdbc(
url,
"(SELECT CAST(column AS date) date, * FROM table) AS tmp",
...
)
然后:
df.filter(psf.col('date') == date)
如果您不打算分发阅读流程或使用动态查询,您还可以使用predicates
:
spark.read.jdbc(
...,
predicates=["CAST(column AS date) = '{}'".format(date)])
)