地图RDD操作中的SCALA多个嵌套case语句

时间:2017-11-07 21:01:43

标签: scala date apache-spark case

我有一个包含7个字符串元素的RDD linesData:org.apache.spark.rdd.RDD [(String,String,String,String,String,String,String)] 我需要为每条记录弄清楚以下两项:状态和CSrange。

逻辑如下:

case when a(6)=0 
    if Date(a(5)) > Date(a(4)) then
        if Date(a(5)) - Date(a(4)) > 60 days then
            staus = '60+'
        else 
            status = 'Curr'
        endif
    else
        status = 'Curr'
    end
when (a(6) >=1 and a(6) <=3 ) then
        Status = 'In-Forcl'
when (a(6) >=4 and a(6) <=8)
    Status = 'Forclosed'
else 
    Status = 'Unknown' 
end case


case  when  (a(1) <640 and a(1) >0 ) then CSrange = '<640'
      when (a(1) <650 and a(1)> 579 then CSrange = '640-649'
      when (a(1) <660 and a(1)> 619 then CSrange = '650-659'
      when (a(1) <680 and a(1)> 639 then CSrange = '640-649'
      when (a(1) >789 then CSrange = '680+'
else    
      CSRange ='Unknown'
end case

此时,我想将数据写入磁盘,可能有9个元素,其中包含7个元素。(稍后我将需要通过各种元素计算上述每种状态的速率)。

我的第一个问题是: 1.如何做日期算术?因为我需要保持在RDD级别(没有数据帧)。 2.我不知道如何在SCALA中执行CASE语句。

示例数据:

(2017_7_0555,794,Scott,CORNERSTONE,8/1/2017,8/1/2017,0)
(2017_7_0557,682,Hennepin,LAKE AREA MT,9/1/2017,8/1/2017,0)
(2017_7_0565,754,Ramsey,GUARANTEED R,6/1/2017,8/1/2017,0)
(2017_7_0570,645,Hennepin,FAIRWAY INDE,2/1/2015,8/1/2017,5)
(2017_7_0574,732,Wright,GUARANTEED R,7/1/2017,8/1/2017,0)
(2017_7_0575,789,Hennepin,GUARANTEED R,8/1/2017,8/1/2017,0)
(2017_7_0577,662,Hennepin,MIDCOUNTRY,8/1/2017,8/1/2017,0)
(2017_7_4550,642,Mower,WELLS FARGO,5/1/2017,8/1/2017,0)
(2017_7_4574,689,Hennepin,RIVER CITY,8/1/2017,8/1/2017,0)
(2017_7_4584,662,Hennepin,WELLS FARGO,8/1/2017,8/1/2017,0)
(2017_7_4600,719,Ramsey,PHH HOME LOA,5/1/2017,8/1/2017,0)

1 个答案:

答案 0 :(得分:0)

我将创建一个包含七个字段的案例类,并将RDD [( ...)]映射到RDD [MyClass]并转换为适当的类型。我建议您使用JodaTime日期库来表示日期。这将使您的代码更具描述性。

然后在地图中将状态和范围提取为两个函数:

myRDD.map(myInstance => (getStatus(myInstance), getRange(myInstance)))

def getStatus(myInstance: MyClass) : String = {
    val (_,_,_,_,date4,date5,field6,_) = MyClass.unapply(myInstance).get
    field6 match {
        case 0 => {
            if(date5.isAfter(date4) {
               if(date4.plusDays(60).isAfter(date5)){
                   "60+"
               } else {
                   "Curr"
               }
            }
        }
        case x if (x >= 1 && x <= 3) => "Forclosed"
        ....
    } 
}

注意:

  • 我没有测试过代码。
  • 重命名示例中的变量。
  • 我向您展示了如何管理JodaTime日期和scala模式匹配的示例。您必须完成该功能并定义另一个功能。