복붙노트

[SCALA] 점화 / 스칼라 여러 열에서 동일한 기능을 사용 withColumn ()에 호출을 반복

SCALA

점화 / 스칼라 여러 열에서 동일한 기능을 사용 withColumn ()에 호출을 반복

나는 현재 내가 반복 .withColumn의 여러 체인을 통해 여러 DataFrame 열 동일한 절차를 적용하는 코드를 가지고 있고, 절차를 간소화하는 기능을 작성하고자하고있다. 내 경우, 나는 키가 집계 열 이상 누적 합계를 찾는하고 있습니다 :

val newDF = oldDF
  .withColumn("cumA", sum("A").over(Window.partitionBy("ID").orderBy("time")))
  .withColumn("cumB", sum("B").over(Window.partitionBy("ID").orderBy("time")))
  .withColumn("cumC", sum("C").over(Window.partitionBy("ID").orderBy("time")))
  //.withColumn(...)

내가하고 싶은 것은 같은 중 하나 일 수 있습니다 :

def createCumulativeColums(cols: Array[String], df: DataFrame): DataFrame = {
  // Implement the above cumulative sums, partitioning, and ordering
}

또는 더 나은 아직 :

def withColumns(cols: Array[String], df: DataFrame, f: function): DataFrame = {
  // Implement a udf/arbitrary function on all the specified columns
}

해결법

  1. ==============================

    1.당신은 가변 인자는 *를 포함하여 선택 사용할 수 있습니다 :

    당신은 가변 인자는 *를 포함하여 선택 사용할 수 있습니다 :

    import spark.implicits._
    
    df.select($"*" +: Seq("A", "B", "C").map(c => 
      sum(c).over(Window.partitionBy("ID").orderBy("time")).alias(s"cum$c")
    ): _*)
    

    이:

    와 같이 일반화 할 수 있습니다 :

    import org.apache.spark.sql.{Column, DataFrame}
    
    /**
     * @param cols a sequence of columns to transform
     * @param df an input DataFrame
     * @param f a function to be applied on each col in cols
     */
    def withColumns(cols: Seq[String], df: DataFrame, f: String => Column) =
      df.select($"*" +: cols.map(c => f(c)): _*)
    

    당신은 withColumn 당신이 foldLeft을 사용할 수 있습니다 더 읽기 구문 찾을 경우 :

    Seq("A", "B", "C").foldLeft(df)((df, c) =>
      df.withColumn(s"cum$c",  sum(c).over(Window.partitionBy("ID").orderBy("time")))
    )
    

    실시 예에 대해 일반화 될 수있다 :

    /**
     * @param cols a sequence of columns to transform
     * @param df an input DataFrame
     * @param f a function to be applied on each col in cols
     * @param name a function mapping from input to output name.
     */
    def withColumns(cols: Seq[String], df: DataFrame, 
        f: String =>  Column, name: String => String = identity) =
      cols.foldLeft(df)((df, c) => df.withColumn(name(c), f(c)))
    
  2. ==============================

    2.질문은 조금 오래된, 그러나 나는 그것이 DataFrame를 사용하여 열 목록을 통해 접는 열 수가 아닌 실질적으로 서로 다른 성능 결과를 한 때 DataFrame 이상 축적 및 매핑으로 참고로 (다른 사람을 위해 아마) 도움이 될 것이라고 생각 사소한합니다 (자세한 설명은 여기 참조). 괜찮 foldLeft 몇 열에 대한 긴 이야기 짧은 ..., 그렇지 않으면지도가 더 좋다.

    질문은 조금 오래된, 그러나 나는 그것이 DataFrame를 사용하여 열 목록을 통해 접는 열 수가 아닌 실질적으로 서로 다른 성능 결과를 한 때 DataFrame 이상 축적 및 매핑으로 참고로 (다른 사람을 위해 아마) 도움이 될 것이라고 생각 사소한합니다 (자세한 설명은 여기 참조). 괜찮 foldLeft 몇 열에 대한 긴 이야기 짧은 ..., 그렇지 않으면지도가 더 좋다.

  3. from https://stackoverflow.com/questions/41400504/spark-scala-repeated-calls-to-withcolumn-using-the-same-function-on-multiple-c by cc-by-sa and MIT license