Voy a añadir una nueva columna a una dataframe con la expresión.
por ejemplo, yo tengo un dataframe de

+-----+----------+----------+-----+
| C1  | C2       |   C3     |C4   |
+-----+----------+----------+-----+
|steak|1         |1         |  150|
|steak|2         |2         |  180|
| fish|3         |3         |  100|
+-----+----------+----------+-----+

y quiero crear una nueva columna C5 con la expresión «C2/C3+C4», asumiendo que hay varias nuevas columnas necesario agregar, y las expresiones pueden ser diferentes y provienen de la base de datos.

¿Hay una buena manera de hacer esto?

Sé que si tengo una expresión como «2+3*4» puedo usar el scala.herramientas.reflejar.Caja de herramientas para eval ella.

Y normalmente estoy usando df.withColumn para agregar nueva columna.

Parece necesito crear una UDF, pero ¿cómo puedo pasar las columnas de valor como parámetros para UDF? especialmente hay tal vez varios expresión de la necesidad de diferentes columnas de calcular.

InformationsquelleAutor Robin Wang | 2017-09-07

3 Comentarios

  1. 16

    Esto se puede hacer utilizando expr para crear un Column a partir de una expresión:

    val df = Seq((1,2)).toDF("x","y")
    
    val myExpression = "x+y"
    
    import org.apache.spark.sql.functions.expr
    
    df.withColumn("z",expr(myExpression)).show()
    
    +---+---+---+
    |  x|  y|  z|
    +---+---+---+
    |  1|  2|  3|
    +---+---+---+
  2. 5

    Dos enfoques:

        import spark.implicits._ //so that you could use .toDF
        val df = Seq(
          ("steak", 1, 1, 150),
          ("steak", 2, 2, 180),
          ("fish", 3, 3, 100)
        ).toDF("C1", "C2", "C3", "C4")
    
        import org.apache.spark.sql.functions._
    
        //1st approach using expr
        df.withColumn("C5", expr("C2/(C3 + C4)")).show()
    
        //2nd approach using selectExpr
        df.selectExpr("*", "(C2/(C3 + C4)) as C5").show()
    
    +-----+---+---+---+--------------------+
    |   C1| C2| C3| C4|                  C5|
    +-----+---+---+---+--------------------+
    |steak|  1|  1|150|0.006622516556291391|
    |steak|  2|  2|180| 0.01098901098901099|
    | fish|  3|  3|100| 0.02912621359223301|
    +-----+---+---+---+--------------------+
  3. 2

    En La Chispa De La 2.x, puede crear una nueva columna C5 con la expresión «C2/C3+C4» el uso de withColumn() y org.apache.spark.sql.functions._,

     val currentDf = Seq(
                  ("steak", 1, 1, 150),
                  ("steak", 2, 2, 180),
                  ("fish", 3, 3, 100)
                ).toDF("C1", "C2", "C3", "C4")
    
     val requiredDf = currentDf
                       .withColumn("C5", (col("C2")/col("C3")+col("C4")))

    También, usted puede hacer lo mismo usando org.apache.spark.sql.Column así.
    (Pero el espacio de la complejidad es un poco mayor en este enfoque que el uso de org.apache.spark.sql.functions._ debido a la Columna de la creación de objetos)

     val requiredDf = currentDf
                       .withColumn("C5", (new Column("C2")/new Column("C3")+new Column("C4")))

    Esto funcionó a la perfección para mí. Estoy usando Chispa 2.0.2.

    • Esto no es tan flexible como el uso de expr función, pero esto puede tener un mejor rendimiento, creo.
    • Sí, Robin. Creo que esto es mejor para expresiones muy sencillas. Para las expresiones complejas, expr función siempre es mejor ya que es más flexible y fácil de mantener.
    • Otra ventaja es que usted puede detectar más problemas en el tiempo de compilación en lugar de la ejecución. Debido a col (» » ), se puede detectar la columna de la disponibilidad en el momento de la compilación.
    • eso no es cierto, no tiene tiempo de compilación comprobar la existencia de columnas

Dejar respuesta

Please enter your comment!
Please enter your name here