2015-10-19 83 views
9

我有一个Spark SQL DataFrame与数据,我想要得到的是在给定的日期范围内当前行之前的所有行。所以举个例子,我希望在给定行之前的7天之后有所有的行。我想我需要使用Window Function比如:Spark窗口函数 - 范围之间的日期

Window \ 
    .partitionBy('id') \ 
    .orderBy('start') 

问题在于这里。我希望7天有rangeBetween,但Spark文档中没有任何内容可以找到。 Spark是否提供这样的选择?现在我只是让所有的前行与:

.rowsBetween(-sys.maxsize, 0) 

,但想实现这样的:

.rangeBetween("7 days", 0) 

如果有人可以帮助我在这一个,我会非常感激。提前致谢!

回答

21

据我所知,在Spark和Hive中都不可能直接存在。两者都要求与RANGE一起使用的ORDER BY子句是数字。我发现的最接近的是转换为时间戳,并在秒钟上运行。假设start列包含date类型:

from pyspark.sql import Row 

row = Row("id", "start", "some_value") 
df = sc.parallelize([ 
    row(1, "2015-01-01", 20.0), 
    row(1, "2015-01-06", 10.0), 
    row(1, "2015-01-07", 25.0), 
    row(1, "2015-01-12", 30.0), 
    row(2, "2015-01-01", 5.0), 
    row(2, "2015-01-03", 30.0), 
    row(2, "2015-02-01", 20.0) 
]).toDF().withColumn("start", col("start").cast("date")) 

一个小帮手和窗口定义:

from pyspark.sql.window import Window 
from pyspark.sql.functions import mean, col 


# Hive timestamp is interpreted as UNIX timestamp in seconds* 
days = lambda i: i * 86400 

最后查询:

w = (Window() 
    .partitionBy(col("id")) 
    .orderBy(col("start").cast("timestamp").cast("long")) 
    .rangeBetween(-days(7), 0)) 

df.select(col("*"), mean("some_value").over(w).alias("mean")).show() 

## +---+----------+----------+------------------+ 
## | id|  start|some_value|    mean| 
## +---+----------+----------+------------------+ 
## | 1|2015-01-01|  20.0|    20.0| 
## | 1|2015-01-06|  10.0|    15.0| 
## | 1|2015-01-07|  25.0|18.333333333333332| 
## | 1|2015-01-12|  30.0|21.666666666666668| 
## | 2|2015-01-01|  5.0|    5.0| 
## | 2|2015-01-03|  30.0|    17.5| 
## | 2|2015-02-01|  20.0|    20.0| 
## +---+----------+----------+------------------+ 

远离漂亮,但工程。


* Hive Language Manual, Types

+0

感谢,我想的是类似的东西,最好有它证实! – Nhor