在pyspark中两次过滤数据

时间:2018-08-25 13:15:18

标签: apache-spark pyspark apache-spark-sql

我有一个从CSV导入的数据框,其中有两列(以及其他列):日期和时间。日期是格式为YYYY-MM-DD的日期字符串,而时间是格式为HH:MM的字符串。当使用inferSchema将其导入pyspark时,“日期”会自动推断为日期时间,从而将其全部解析为午夜(例如2018-05-04 00:00:00.000)。

我需要将数据筛选为仅时间在两个小时(上午9点至下午5点)之间的数据。我最基本的想法是仅对字符串进行过滤,例如

return dataframe.filter( dataframe.Time.like("19%") )

或者,我想到将日期和时间汇总到单个“时间戳”列中,如下所示(可能非常糟糕,我仍在学习pyspark):

data = data.withColumn( "Timestamp", to_utc_timestamp(concat(date_format(col("Date"), "YYYY-MM-dd "), col("Time")), "GMT") # )

基本上,由于我对这两种方法都不感到兴奋,我该怎么做?如果第二种方法看起来合理,那么如何执行过滤器呢?第二种方法的缺点是,它使数据框带有新列,这是潜在的无法预料的副作用(我正在尝试以模块化方式构建此代码)。

先谢谢了。抱歉,这个问题含糊不清,我仍在探索pyspark,并试图了解完成事情的各种可能方式。

1 个答案:

答案 0 :(得分:1)

  

使用inferSchema将其导入pyspark时,“日期”会自动推断为日期时间,从而将其全部解析为午夜(例如2018-05-04 00:00:00.000)

为此,您应该使用date_format(col('Date'), 'yyyy-MM-dd'),它将从日期时间中提取日期并将列转换为StringType

现在日期和时间都是StringType,您可以使用concat_ws(' ', date_format(col('Date'), 'yyyy-MM-dd'), col('Time'))来同时连接日期和时间

现在日期和时间都已连接,您可以使用to_timestamp(concat_ws(' ', date_format(col('Date'), 'yyyy-MM-dd'), col('Time')), 'yyyy-MM-dd HH:mm')将StringType dateTime转换为时间戳

并使用小时功能提取小时,最后使用过滤器过滤数据框

因此工作代码应为

from pyspark.sql.functions import *
df = df.withColumn('hourOfDay', hour(to_timestamp(concat_ws(' ', date_format(col('Date'), 'yyyy-MM-dd'), col('Time')), 'yyyy-MM-dd HH:mm')))\
        .filter((col('hourOfDay') >= lit(9)) & (col('hourOfDay') <= lit(17)))\
        .drop('hourOfDay')

这应该给出您过滤后的期望输出

我希望答案会有所帮助