pyspark最有效的日期 - 时间戳匹配

时间:2018-06-08 15:06:37

标签: python apache-spark pyspark

我有一个带有时间戳类型列的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)
)

1 个答案:

答案 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)])
)

embed selection in the table definition