Cómo convertir el caso a cuando de otro modo en marcos de datos de chispa

Me gustaría reescribir el código teradata para generar marcos de datos usando scala, enfrentando un error "cuando() no se puede aplicar una vez más() se aplica ", Ayuda es apreciada.

Teradata

  CASE WHEN
    CASE WHEN ID <> cid OR Group <> sg OR ead IS NULL THEN 1 
    ELSE 
        CASE WHEN HFlag <> hg AND ad + TBreak < ActivityDate THEN 1 
        ELSE 
          CASE WHEN HFlag = hg AND HFlag = 1 THEN 
            CASE WHEN ead + 1 < ActivityDate THEN 
              CASE WHEN ead + TBreak < ActivityDate THEN 1 
              ELSE 0 END 
            ELSE 0 END 
            WHEN HFlag = hg AND HFlag = 0 THEN 
            CASE WHEN ead + TBreak < ActivityDate THEN 1 
            ELSE 0 END 
          ELSE 0 END 
        END 
    END = 1 THEN Row_Number() Over(ORDER BY ID, Group, ActivityDate, HFlag) 
    ELSE 0 END AS arctic

Lo intenté de la siguiente manera.

val windowRank = Window.orderBy('ID, 'Group, 'ActivityDate, 'HFlag)

  df.withColumn("arctic",
    when(when(col("ID") =!= col("cid") || col("Group") =!= col("sg") || col("ad").isNull, 1)
      .when(col("HFlag") =!= col("hg") && (col("ad") + col("TBreak")) < col("ActivityDate"), 1)
      .when(col("HFlag") === col("hg") && col("HFlag") === 1,
        when((col("ad") + 1) < col("ActivityDate"),
          when((col("ad") + col("TBreak")) < col("ActivityDate"), 1)
            .otherwise(0))
          .otherwise(0)
          .when(col("HFlag") === col("hg") && col("HFlag") === 0, when((col("ad") + col("TBreak")) < col("ActivityDate"), 1))
          .otherwise(0))
      .otherwise(0) === 1, row_number() over windowRank)
      .otherwise(0))

Pregunta hecha hace 3 años, 4 meses, 28 días - Por pixelprodigy


3 Respuestas:

  • Te has perdido un corchete de cierre

    val windowRank = Window.orderBy('ID, 'Group, 'ActivityDate, 'HFlag)
    
      df.withColumn("arctic",
        when(when(col("ID") =!= col("cid") || col("Group") =!= col("sg") || col("ad").isNull, 1)
          .when(col("HFlag") =!= col("hg") && (col("ad") + col("TBreak")) < col("ActivityDate"), 1)
          .when(col("HFlag") === col("hg") && col("HFlag") === 1,
            when((col("ad") + 1) < col("ActivityDate"),
              when((col("ad") + col("TBreak")) < col("ActivityDate"), 1)
                .otherwise(0))
              .otherwise(0))  // <-- missing close bracket
              .when(col("HFlag") === col("hg") && col("HFlag") === 0, when((col("ad") + col("TBreak")) < col("ActivityDate"), 1))
              .otherwise(0))
          .otherwise(0) === 1, row_number() over windowRank)
          .otherwise(0))
    

    Respondida el Dec 17, 2020 a las 05:40 - por syntaxsorcerer

    Votos positivos: 0 | Votos negativos: 0

  • El error que estás experimentando se debe a cómo estás encadenando múltiples llamadas al método when() en Spark DataFrame API. En Spark, el método when() se utiliza para definir condiciones condicionales en columnas y no se puede anidar orientándolas de la misma manera que en SQL.

    Para convertir el caso a "cuando de otro modo" en marcos de datos de Spark, puedes utilizar el método expr para definir expresiones condicionales más complejas. Aquí te muestro cómo podrías reformular tu código para manejar el caso de otra manera:

    scala
    import org.apache.spark.sql.functions._
    import org.apache.spark.sql.expressions.Window
    
    val windowRank = Window.orderBy("ID", "Group", "ActivityDate", "HFlag")
    
    val resultDf = df.withColumn("arctic",
      expr(
        """
        CASE
        WHEN (ID <> cid OR Group <> sg OR ead IS NULL) THEN 1
        WHEN (HFlag <> hg AND ad + TBreak < ActivityDate) THEN 1
        WHEN (HFlag = hg AND HFlag = 1 AND ead + 1 < ActivityDate AND ead + TBreak < ActivityDate) THEN 1
        WHEN (HFlag = hg AND HFlag = 0 AND ead + TBreak < ActivityDate) THEN 1
        ELSE 0
        END
        """
      )
    )
    
    resultDf.show()
    

    En este código, hemos utilizado la función de expr para definir la lógica condicional de una manera más legible y sencilla. Esto debería ayudarte a evitar el error que estás enfrentando al intentar encadenar múltiples llamadas al método when(). Por favor, inténtalo y avísame si tienes alguna otra pregunta.

    Respondida el Dec 18, 2020 a las 05:42 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • El error "when() no se puede aplicar una vez más() se aplica" en Apache Spark se produce cuando se intenta encadenar funciones when() múltiples sin utilizar una expresión otherwise().

    Para resolver este error, debes agregar una expresión otherwise() después de cada when(). Esto garantiza que se proporciona un valor predeterminado para cada rama de la expresión condicional.

    Además, la función row_number() en Apache Spark requiere una partición de ventana para funcionar correctamente. En tu código, no has especificado una partición de ventana, lo que podría provocar otro error.

    Aquí tienes el código corregido:

    scala
    val windowRank = Window.partitionBy('ID, 'Group).orderBy('ActivityDate, 'HFlag)
    
    df.withColumn("arctic",
      when(when(col("ID") =!= col("cid") || col("Group") =!= col("sg") || col("ad").isNull, 1)
        .when(col("HFlag") =!= col("hg") && (col("ad") + col("TBreak")) < col("ActivityDate"), 1)
        .when(col("HFlag") === col("hg") && col("HFlag") === 1,
          when((col("ad") + 1) < col("ActivityDate"),
            when((col("ad") + col("TBreak")) < col("ActivityDate"), 1)
              .otherwise(0))
            .otherwise(0)
          .when(col("HFlag") === col("hg") && col("HFlag") === 0, when((col("ad") + col("TBreak")) < col("ActivityDate"), 1))
          .otherwise(0))
        .otherwise(0) === 1, row_number() over windowRank)
      .otherwise(0))
    

    Ten en cuenta que la partición de ventana se ha especificado mediante Window.partitionBy('ID, 'Group). Esto garantiza que los valores de row_number() se calculen por separado para cada partición de ID y Group.

    Respondida el Dec 18, 2020 a las 05:47 - por Gemini

    Votos positivos: 0 | Votos negativos: 0