使用Spark按优先级规则过滤Spark数据帧中的数据

时间:2017-06-04 09:08:04

标签: scala apache-spark apache-spark-sql

我有一个数据帧df,下面提到了一些示例记录:

**customers**   **product**   **val_id**  
     1               A            1  
     2               C            r 
     3               B            X    
     4               D            X  
     5               E            1 
     6               F            9

我必须对这些数据应用一些n规则,一些示例规则是:

名称:规则1,ID:1

filter out customers who have product A and B, rule priority is 1

名称:规则2,ID:2

filter out customers who have product A, B,C and F, rule priority is 3

名称:规则3,ID:3

filter out customers who have product C and E, rule priority is 2

要求是创建一个新的数据框并过滤掉那些从这些规则传递的客户,并提及他们通过的规则,从优先级1 规则传递的客户不应由优先级较低的规则和从优先级2 规则传递的客户不应由低优先级规则处理,等等。

所以我的最终数据框应该是:

**customers**   **product**   **val_id**   **rule_name**   **rule_id** 
     1               A            1              Rule1           1
     2               C            r              Rule3           3
     3               B            X              Rule1           1
     5               E            1              Rule3           3
     6               F            9              Rule2           2

使用Spark Scala可以帮助我解决这个问题。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

您可以通过将udfrule_name列的rule_id函数定义为

来解决此问题
def rule_name = udf((product : String) => {
  if(Seq("A", "B").contains(product)) "Rule1"
  else if(Seq("A", "B", "C", "F").contains(product)) "Rule3"
  else if(Seq("C", "E").contains(product)) "Rule2"
  else ""
})

def rule_id = udf((product : String) => {
  if(Seq("A", "B").contains(product)) "1"
  else if(Seq("A", "B", "C", "F").contains(product)) "3"
  else if(Seq("C", "E").contains(product)) "2"
  else ""
})

然后使用udf函数

调用这些withColumn函数
val ruledDF = dataframe.withColumn("rule_name" , rule_name(col("product")))
  .withColumn("rule_id" , rule_id(col("product")))

最后filter使用空规则rows

ruledDF.filter(!(ruledDF("rule_name") === ""))

这应该满足您的要求。

答案 1 :(得分:0)

尝试这样的事情:

val rule_name = when(col("product").isin("A","B"), "ABC").otherwise(when(col("product").isin("A","B","D"), "DEF").otherwise(""))
val rule_id = when(col("product").isin("A","B"), "123").otherwise(when(col("product").isin("A","B","D"), "456").otherwise(""))
val df1 = df_customers.withColumn("rule_name" , rule_name).withColumn("rule_id" , rule_id)
df1.show()

这是一个示例,可能不是一个确切的解决方案,但您将能够解决您的问题。