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

Posted

技术标签:

【中文标题】pyspark 最有效的日期时间戳匹配【英文标题】:pyspark most efficient date-timestamp matching 【发布时间】:2018-06-08 15:06:37 【问题描述】:

我有一个带有时间戳类型列的 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 读入的,可能不会被分发。

这是我尝试过的(没有注意到重大差异),哪个更可取?我错过了什么吗?

方法一:转换为日期

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)
)

【问题讨论】:

您能否edit 您的问题添加df.printSchema() 的输出。我可以想象一种方法,根据日、月和年的偏差,第二种方法可以更快。例如,如果几天的第一个过滤器比一年的最后一次检查更频繁地失败,那么您检查的方式是最佳的。但是,例如,如果您的许多日期都在该月的第一天,那么它会变慢。 我添加了printSchema()!对于这个例子,让我们假设我们不知道提前日期的分布。第一种方法会更安全吗? 通过 JDBC 从 SQL Server 读取 【参考方案1】:

这是我尝试过的(没有注意到重大差异),哪个更可取?

两者都没有。这两种方法效率低下,无法充分利用数据库和 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。

【讨论】:

粗糙!这大大加快了速度。更好的是在 SQL 查询中进行过滤(这对于我的特殊情况是可能的)。

以上是关于pyspark 最有效的日期时间戳匹配的主要内容,如果未能解决你的问题,请参考以下文章

在熊猫中获取与给定日期时间最接近的时间戳的行的有效方法

创建函数以使当前日期以没有时间戳的字符串格式显示的最有效方法是啥? [复制]

在pyspark数据框中的两个日期之间生成每月时间戳

Pyspark 将字符串转换为日期时间戳列,包含两种不同的格式

如何将所有日期格式转换为日期列的时间戳?

来自时间戳和国家/地区的 pyspark 时区转换