根据Hive中的前一行计算风险评分

时间:2016-12-10 08:58:30

标签: scala hive hiveql

我有一个问题,就是根据customer_id中的Hive中的前一行来计算风险评分。 我对scala和hive很新。

例如,这是我的表Temp1:

customer_id recency_score period_start period_end
a           4             201501       201512
a           4             201502       201601
a           3             201503       201602
a           3             201504       201603
a           2             201505       201604
a           2             201506       201605
a           2             201507       201606
a           2             201508       201607
a           2             201509       201608
a           2             201510       201609
a           2             201511       201610
a           2             201512       201611
b           4             201501       201512
b           4             201502       201601
b           3             201503       201602
b           3             201504       201603
b           3             201505       201604
b           3             201506       201605
b           4             201507       201606
b           3             201508       201607
b           2             201509       201608
b           3             201510       201609
b           2             201511       201610
b           2             201512       201611

风险评分应为:

    如果recency_score在两个时段之间没有下降,则
  • 0
  • 如果recency_score在两个时段之间下降,则
  • 1
  • 2如果recency_score在两个时段之间下降,则保持在同一级别
  • 3如果recency_score在两个时段之间下降然后再次下降

这部分非常容易,我已经找到了如何做到这一点,但我想在下一行考虑前面的结果,我的意思是如果之前的risk_score已经是2并且recency_score下降了新的risk_score将是3,如果recency_score保持稳定,那么它将保持在2。

实际上,我不知道如何将“记忆”保留在以前的risk_score中。

还有一件事,每个customer_id的行数各不相同(对于一个customer_id,它可以是12,对于另一个,它可以是8,对于另一个,它可以是3 ......)

所以我想要这样的事情:

customer_id recency_score period_start period_end risk_score
a           4             201501       201512     0
a           4             201502       201601     0
a           3             201503       201602     1
a           3             201504       201603     2
a           2             201505       201604     3
a           2             201506       201605     3
a           2             201507       201606     3
a           2             201508       201607     3
a           2             201509       201608     3
a           2             201510       201609     3
a           2             201511       201610     3
a           2             201512       201611     3
b           4             201501       201512     0
b           4             201502       201601     0
b           3             201503       201602     1
b           3             201504       201603     2
b           3             201505       201604     2
b           3             201506       201605     2
b           4             201507       201606     0
b           3             201508       201607     1
b           2             201509       201608     3
b           3             201510       201609     0
b           2             201511       201610     1
b           2             201512       201611     2

如果您对我有一些想法,我将不胜感激

BR,Sophie

1 个答案:

答案 0 :(得分:1)

这不是一个完整的解决方案,但使用评论太长了,它可能会有所帮助。您可以使用window function lag来“保留”以前的任何状态。此函数将行移动特定数量的位置(默认情况下为1)。例如,这句话将使用前一个recency_score创建一个额外的列(您可以应用相同的逻辑来存储您想要的任何“先前”状态。)

val table_modified = spark.sql("SELECT customer_id, recency_score, period_start, period_end, 
LAG(recency_score) OVER (PARTITION BY customer_id ORDER BY period_start) AS previous
FROM Temp1")

请注意,您需要提供订单(在本例中为period_start列)和一个组(在本例中为客户)。添加列后,您可以修改具有先前状态的表(尽管这不是必需的)。这将生成下表:

scala> table_modified.createOrReplaceTempView("Temp1")
scala> table_modified.show(100)
+-----------+-------------+------------+----------+--------+
|customer_id|regency_score|period_start|period_end|previous|
+-----------+-------------+------------+----------+--------+
|          b|            4|      201501|    201512|    null|
|          b|            4|      201502|    201601|       4|
|          b|            3|      201503|    201602|       4|
|          b|            3|      201504|    201603|       3|
|          b|            3|      201505|    201604|       3|
|          b|            3|      201506|    201605|       3|
|          b|            4|      201507|    201606|       3|
|          b|            3|      201508|    201607|       4|
|          b|            2|      201509|    201608|       3|
|          b|            3|      201510|    201609|       2|
|          b|            2|      201511|    201610|       3|
|          b|            2|      201512|    201611|       2|
|          a|            4|      201501|    201512|    null|
|          a|            4|      201502|    201601|       4|
|          a|            3|      201503|    201602|       4|
|          a|            3|      201504|    201603|       3|
|          a|            2|      201505|    201604|       3|
|          a|            2|      201506|    201605|       2|
|          a|            2|      201507|    201606|       2|
|          a|            2|      201508|    201607|       2|
|          a|            2|      201509|    201608|       2|
|          a|            2|      201510|    201609|       2|
|          a|            2|      201511|    201610|       2|
|          a|            2|      201512|    201611|       2|
+-----------+-------------+------------+----------+--------+

创建后,您可以将所需的逻辑应用于行,因为它们中的每个都在行中具有“先前”分数。

我希望这会有所帮助。