создание пользовательских линеек с использованием функции when

#scala #apache-spark #apache-spark-sql

#scala #apache-spark #apache-spark-sql

Вопрос:

Я пытаюсь создать пользовательские правила с помощью функции «when», чтобы, наконец, применить их к столбцу фрейма данных. Многие из этих правил будут применяться к разным столбцам, но идея не в том, чтобы записывать их для каждого столбца, а в том, чтобы сохранить их в переменной и объединить. Например, у меня есть следующее:

 df
.withColumn("campoOut1",when(col("campo1") === "G" amp;amp; col("campo2") === "00", "001"))
.withColumn("campoOut2",
    when(col("campo1") === "G" amp;amp; col("campo2") === "00", "001").
    when(col("campo3") === "G" amp;amp; col("campo4") =!= "00", "002"))
  

и я хочу добиться следующего :

 val ruler1 = when(col("campo1") === "G" amp;amp; col("campo2") === "00", "001")
val ruler2 = when(col("campo3") === "G" amp;amp; col("campo4") =!= "00", "002")

 df.withColumn("campoOut1",ruler1)
   .withColumn("campoOut2",ruler1   ruler2)
  

Я не добился успеха, потому что переменные ruler1 и ruler2 не имеют типа «string», есть идеи, как это сделать?

заранее большое вам спасибо

Ответ №1:

вы могли бы рекурсивно связать правила:

 def chainRules(rules: (Column, String)*) = {
     def go(rules: Seq[(Column, String)], chained: Column): Column = {
        if (rules.isEmpty) {
           return chained
        }
        go(rules.tail, chained.when(rules.head._1, rules.head._2))
     }
     go(rules.tail, when(rules.head._1, rules.head._2))
  }
  

но вам нужно будет адаптировать свои правила таким образом:

 val rule1 = (col("campo1") === "G" amp;amp; col("campo2") === "00", "001")
val rule2 = (col("campo3") === "G" amp;amp; col("campo4") =!= "00", "002")
  

чем вы можете использовать это так:

  df.withColumn("campoOut1", chainRules(rule1))
   .withColumn("campoOut2", chainRules(rule1, rule2))
  

Комментарии:

1. Неплохо. Один вопрос, что означает звездочка после круглых скобок? правила: (столбец, строка)*

2. его версия scalas переменных аргументов. def x(vars: String*) = println(x) позволяет использовать x таким образом: x("multiple", "arguments", "in", "here") в самой функции это будет WrappedArray

3. Я понимаю, есть ли другой способ написать код без использования «return»? intellij Idea обнаруживает это как плохую практику

4. Оберните второе условие в другое, чем вы можете удалить возврат