模仿'分组来自'和

时间:2015-10-07 11:50:33

标签: apache-spark

我有一个包含csv列的大型id,time,location文件。我将它设为RDD,并且想要计算trips的一些聚合度量,当旅程被定义为相同id的时间连续记录集时,在任一侧至少相隔1小时。我是新来的火花。 (related

为此,我想创建一个包含(trip_id,(time, location))形式元素的RDD,并使用reduceByKey来计算所有需要的指标。

为了计算trip_id,我尝试实现链接问题的SQL方法,制作一个指标字段,记录该记录是否为旅行的开始,并对该指标字段进行累计求和。这听起来不像分布式方法:有更好的方法吗?

此外,如何添加此指标字段?如果与同一id的前一记录的时差超过一小时,则它应为1,否则为0。我首先想到groupBy id,然后对每个值进行排序,但它们将在一个数组中,因此不适合sortByKey,并且没有lead函数在SQL中获取以前的值。

建议的上述方法的

示例:对于RDD

(1,9:30,50)
(1,9:37,70)
(1,9:50,80)
(2,19:30,10)
(1,20:50,20)

我们希望首先将其转换为具有时差的RDD,

(1,9:30,50,inf)
(1,9:37,70,00:07:00)
(1,9:50,80,00:13:00)
(2,19:30,10,inf)
(2,20:50,20,01:20:00)

(最早的记录的值是scala' s PositiveInfinity常数)

并将此最后一个字段转换为指示字段,该字段是否大于1,表示我们是否开始旅行,

(1,9:30,50,1)
(1,9:37,70,0)
(1,9:50,80,0)
(2,19:30,10,1)
(2,20:50,20,1)

然后将其转换为trip_id

(1,9:30,50,1)
(1,9:37,70,1)
(1,9:50,80,1)
(2,19:30,10,2)
(2,20:50,20,3)

然后使用此trip_id作为聚合的关键。

预处理只是加载文件并删除标题

val rawdata=sc.textFile("some_path")
def isHeader(line:String)=line.contains("id")
val data=rawdata.filter(!isHeader(_))

修改

在尝试使用spark SQL时,我遇到了有关时差的错误:

val lags=sqlContext.sql("
  select time - lag(time) over (partition by id order by time) as diff_time from data
");

因为spark不知道如何区分两个时间戳。我试图检查这个差异是否超过1小时。

它也没有识别我在网上找到的函数getTime作为答案,以下也返回错误(Couldn't find window function time.getTime):

val lags=sqlContext.sql("
  select time.getTime() - (lag(time)).getTime() over (partition by id order by time) 
  from data
");

即使为数字属性创建类似的lag差异,也可以使用

val lag_numeric=sqlContext.sql("
select longitude - lag(longitude) over (partition by id order by time) 
from data");  //works

Spark也没有认识到函数Hours.hoursBetween。我正在使用spark 1.4.0

我还试图定义一个合适的用户定义函数,但奇怪的是在查询中无法识别UDFS:

val timestamp_diff: ((Timestamp,Timestamp) => Double) =
    (d1: Timestamp,d2: Timestamp) => d1.getTime()-d2.getTime()
val lags=sqlContext.sql("select timestamp_diff(time,lag(time)) 
over (partition by id order by time) from data");
  

那么,如何激发测试时间戳之间的差异是否超过一小时?

完整代码

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.sql.SQLContext
import org.apache.spark.sql.functions._
import sqlContext._
val sqlContext = new org.apache.spark.sql.hive.HiveContext(sc)
import sqlContext.implicits._
import org.apache.spark.sql.hive.HiveContext//For window functions
import java.util.Date
import java.sql.Timestamp

case class Record(id: Int, time:Timestamp, longitude: Double, latitude: Double)
val raw_data=sc.textFile("file:///home/sygale/merged_table.csv")

val data_records=
                    raw_data.map(line=>
                           Record( line.split(',')(0).toInt,
                                   Timestamp.valueOf(line.split(',')(1)),
                                   line.split(',')(2).toDouble,
                                   line.split(',')(3).toDouble 
                                  ))                                                                                     

val data=data_records.toDF()
data.registerTempTable("data")
val lags=sqlContext.sql("
  select time - lag(time) over (partition by id order by time) as diff_time from data
");

0 个答案:

没有答案