我有一个带有时间戳类型列的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)
方法二:按年、月、日匹配
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)
)
发布于 2018-06-09 00:06:46
这里是我已经尝试过的(没有注意到主要差异),哪个更可取?
都不是。这两种方法效率都很低,并且不能充分利用数据库和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)])
)
https://stackoverflow.com/questions/50763533
复制相似问题