从分组的RDD中选择最早和最晚的日期

时间:2016-10-10 00:49:03

标签: sql scala apache-spark

我有一个表格的分组RDD(patientID,[Medication]),其中Medication是以下案例类:

case class Medication(patientID: String, date: Date, medicine: String)

RDD由以下行组成:

val grpMeds = medication.groupBy(_.patientID)

如果药物是RDD [药物]形式的RDD。

对于每位患者,我试图找到最早和最晚的某种药物,即“药物_A”,(注意药物是case class Medication的一种方法)。我想要获得的是RDD [patientID,earliestDate,latestDate]格式的RDD,但无法弄清楚如何获得它。

非常感谢任何帮助。数据的外观示例(从grpMeds.take(0).foreach(println)获得)如下所示。

Medication(000961291-01,Tue Jun 21 19:45:00 UTC 2005,Isotonic Saline (0.9%))
Medication(000096430-01,Mon Nov 15 20:45:00 UTC 2010,insulin aspart)

1 个答案:

答案 0 :(得分:3)

使用groupBy是一种非常低效的方法。作为替代,我建议使用Spark SQL或reduceByKey

对于Spark SQL,您应该将medication转换为DataFrame

import spark.implicits._  // import sqlContext.implicits._

val medicationDF = medication.toDF

并使用groupBy后跟agg

medicationDF.groupBy($"patientID", $"medicine").agg(min($"date"), max($"date"))

对于此解决方案,date应为java.sql.Datejava.sql.Timestamp

对于reduceByKey首先,您应该重新塑造medication以获取由patientIdmedicine组成的密钥以及重复date的值:

val medicationPairs = medication.map(m => 
  ((m.patientID, m.medicine), (m.date, m.date))
)

下一个reduceByKey

medicationPairs.reduceByKey { 
  case ((xMin, xMax), (yMin, yMax)) => (
    if(xMin.before(yMin)) xMin else yMin,
    if(xMax.after(yMax))  xMax else yMax
  )
}