2017-06-16 10 views
1

開始日と終了日を含む日付タプルを日付系列に変換する必要があります。Spark SQLの開始日と終了日から日付シリーズを取得するには

-+-----------------------------------------+ 
|dateRange        | 
-+-----------------------------------------+ 
|[2017-04-06 00:00:00,2017-04-05 00:00:00]| 
|[2017-04-05 00:00:00,2017-04-04 00:00:00]| 
|[2017-04-04 00:00:00,2017-04-03 00:00:00]| 
|[2017-04-03 00:00:00,2017-03-31 00:00:00]| 
|[2017-03-31 00:00:00,2017-03-30 00:00:00]| 
|[2017-03-30 00:00:00,2017-03-29 00:00:00]| 
|[2017-03-29 00:00:00,2017-03-28 00:00:00]| 
|[2017-03-28 00:00:00,2017-03-27 00:00:00]| 
|[2017-04-06 00:00:00,2017-04-05 00:00:00]| 
|[2017-04-05 00:00:00,2017-04-04 00:00:00]| 
|[2017-04-04 00:00:00,2017-04-03 00:00:00]| 
|[2017-04-03 00:00:00,2017-03-31 00:00:00]| 
|[2017-03-31 00:00:00,2017-03-30 00:00:00]| 
|[2017-03-30 00:00:00,2017-03-29 00:00:00]| 
|[2017-03-29 00:00:00,2017-03-28 00:00:00]| 
|[2017-03-28 00:00:00,2017-03-27 00:00:00]| 
|[2017-04-06 00:00:00,2017-04-05 00:00:00]| 
-+-----------------------------------------+ 

これらのタプルを 'to'から 'From'の日付シリーズに変換するにはどうすればよいですか?変換後の

|[2017-04-03 00:00:00,2017-03-31 00:00:00]| 

私はコードスニペットと私のためにその作業の下に試してみました

|[2017-04-03 00:00:00,2017-04-02 00:00:00,2017-04-01 00:00:00,2017-03-31 00:00:00]| 
+0

どのようにこの[04-03,04-02,04-01,04-31]に変換しますか?論理は何ですか? –

+0

私は簡単に質問を編集しました。 –

答えて

1

UDFを作成し、fromDatetoDateの間の日付を計算すると、この問題を解決できる可能性があります。私は簡潔にするためにJoda Time APIを使用しました。以下は

libraryDependencies += "joda-time" % "joda-time" % "2.8.1" 

は一例であり、あなたの問題

import spark.implicits._ 

    val data = spark.sparkContext.parallelize(Seq(
     ("2017-04-03 00:00:00,2017-03-31 00:00:00"), 
     ("2017-03-31 00:00:00,2017-03-30 00:00:00"), 
     ("2017-03-30 00:00:00,2017-03-29 00:00:00"), 
     ("2017-03-29 00:00:00,2017-03-28 00:00:00"), 
     ("2017-03-28 00:00:00,2017-03-27 00:00:00"), 
     ("2017-04-03 00:00:00,2017-03-31 00:00:00"), 
     ("2017-04-06 00:00:00,2017-04-05 00:00:00") 
    )).toDF("dateRanges") 


    val calculateDate = udf((date: String) => { 

     val dtf = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss") 

     val from = dtf.parseDateTime(date.split(",")(0)).toDateTime() 
     val to = dtf.parseDateTime(date.split(",")(1)).toDateTime() 
     val dates = scala.collection.mutable.MutableList[String]() 
     var toDate = to 
     while(from.getMillis != toDate.getMillis){ 
      if (from.getMillis > toDate.getMillis){ 
      dates += from.toString(dtf) 
      toDate = toDate.plusDays(1) 
      } 
      else { 
      dates += from.toString(dtf) 
      toDate = toDate.minusDays(1) 
      } 
     } 
     dates 
    }) 

    data.withColumn("newDate", calculateDate(data("dateRanges"))) 

toDateが小さいか大きいあなたの場合、これは両方のケースのために働くために:あなたは、SBTについて

ように、そのいずれかの依存関係を追加する必要がありますfromDateより。

希望すると便利です。

0

に変換する必要があります。

import org.apache.spark.sql.functions._ 
    import org.joda.time.LocalDate 
    def dayIterator(start: LocalDate, end: LocalDate) = Iterator.iterate(start)(_ plusDays 1) takeWhile (_ isBefore end) 

    def dateSeries(date1 : String,date2 : String) : Array[String]= { 
    val fromDate = new LocalDate(date1.split(" ")(0)) 
    val toDate = new LocalDate(date2.split(" ")(0)) 
    val series = dayIterator(fromDate,toDate).toArray 
    val arr = series.map(a => a.toString() + " 00:00:00.0") 
    arr 
    } 

    val DateSeries = udf(dateSeries(_: String, _ : String)) 


scala> dateSeries("2017-03-31 00:00:00.0","2017-04-03 00:00:00.0" 
res53: Array[String] = Array(2017-03-31, 2017-04-01, 2017-04-02) 

ません私も付加した後把握することはできませんよ「00:00:00.0」dateSeries方法でマップ操作で。それが返す配列には、追加された文字列はありません。

関連する問題