在SparkR的DataFrame中按时间戳过滤行

时间:2015-09-06 08:03:34

标签: r apache-spark apache-spark-sql sparkr

我希望按时间戳过滤SparkR中的df <- createDataFrame(sqlContext, data.frame(ID = c(1,2,3), Timestamp=c('08/01/2014 11:18:30', '01/01/2015 12:13:45', '05/01/2015 14:17:33'))) 行,格式如下:

TimeStamp

请注意String列的原始架构为03/01/2015 00:00:00。假设我想在timestamp之前过滤那些时间戳,我认为可能有两种方法可以做到这一点:

一种方法是使用dplyrlubridate将列变为df %>% mutate(Timestamp = mdy_hms(Timestamp)) %>% filter(Timestamp < mdy_hms('03/01/2015 00:00:00')) ,就像普通的R一样:

DataFrame

但是我没有改变Column的列,因为它是S4类DataFrame而不是矢量。

第二种方法可能是将SparkSQL注册为表格,然后使用timestamp来处理df <- createDataFrame(sqlContext, data.frame(ID = c(1,2,3), Timestamp=c('08/01/2014 11:18:30', '01/01/2015 12:13:45', '05/01/2015 14:17:33'))) registerTempTable(df, 'df') head(sql(sqlContext, 'SELECT * FROM df WHERE Timestamp < "03/01/2015 00:00:00"')) 类型:

DAO

但是因为它仍然是一个字符串比较,所以它会给出错误的结果。这样做的正确方法是什么?

1 个答案:

答案 0 :(得分:3)

Spark 1.6 +

您应该可以使用unix_timestamp功能和标准SQLContext

ts <- unix_timestamp(df$Timestamp, 'MM/dd/yyyy HH:mm:ss') %>%
  cast("timestamp")

df %>% 
   where(ts <  cast(lit("2015-03-01 00:00:00"), "timestamp"))

Spark&lt; 1。

这应该可以解决问题:

sqlContext <- sparkRHive.init(sc)

query <- "SELECT * FROM df
    WHERE unix_timestamp(Timestamp, 'MM/dd/yyyy HH:mm:ss') < 
          unix_timestamp('2015-03-01 00:00:00')" # yyyy-MM-dd HH:mm:ss 

df <- createDataFrame(sqlContext, ...)
registerTempTable(df, 'df')

head(sql(sqlContext, query))

##   ID           Timestamp
## 1  1 08/01/2014 11:18:30
## 2  2 01/01/2015 12:13:45

请注意,在此处选择上下文非常重要。由于unix_timestamp是Hive UDF标准SQLContext,因此您在SparkR中默认获得此标准。