¿Alguien puede por favor explicar por qué el caso Row, Seq[Row] se utilizan después de la explosión de una dataframe campo que tiene la colección de elementos.
Y también puede usted por favor me explique la razón por la que asInstanceOf se requiere para obtener los valores de la explotó campo?

Aquí es la sintaxis:

val explodedDepartmentWithEmployeesDF = departmentWithEmployeesDF.explode(departmentWithEmployeesDF("employees")) {     
                          case Row(employee: Seq[Row]) => 
                          employee.map(employee =>
                          Employee(employee(0).asInstanceOf[String], 
                          employee(1).asInstanceOf[String], employee(2).asInstanceOf[String]) ) }
InformationsquelleAutor Ramesh | 2016-08-24

2 Comentarios

  1. 2

    Primero que se nota, que no puedo explicar por qué su explode() se convierte en Row(employee: Seq[Row]) como no sé el esquema de su DataFrame. Tengo que asumir que tiene que ver con la estructura de los datos.

    No sabiendo que los datos originales, he creado un pequeño conjunto de datos para el trabajo de

    scala> val df = sc.parallelize( Array( (1, "dsfds dsf dasf dsf dsf d"), (2, "2344 2353 24 23432 234"))).toDF("id", "text")
    df: org.apache.spark.sql.DataFrame = [id: int, text: string]
    

    Si ahora se asignan a través de ella, se puede ver que devuelve las filas que contengan datos de Cualquier tipo.

    scala> df.map {case row: Row => (row(0), row(1)) }
    res21: org.apache.spark.rdd.RDD[(Any, Any)] = MapPartitionsRDD[17] at map at <console>:33
    

    Tiene básicamente perdió tipo de información, por eso es necesario especificar explícitamente el tipo de cuando usted desea utilizar los datos en la fila

    scala> df.map {case row: Row => (row(0).asInstanceOf[Int], row(1).asInstanceOf[String]) }
    res22: org.apache.spark.rdd.RDD[(Int, String)] = MapPartitionsRDD[18] at map at <console>:33
    

    Así, con el fin de explotar, me tienes que hacer lo siguiente

    scala> :paste
    //Entering paste mode (ctrl-D to finish)
    
    import org.apache.spark.sql.Row
    df.explode(col("id"), col("text")) {case row: Row =>
        val id = row(0).asInstanceOf[Int]
        val words = row(1).asInstanceOf[String].split(" ")
        words.map(word => (id, word))
    }
    
    //Exiting paste mode, now interpreting.
    
    import org.apache.spark.sql.Row
    res30: org.apache.spark.sql.DataFrame = [id: int, text: string, _1: int, _2: string]
    
    scala> res30 show
    +---+--------------------+---+-----+
    | id|                text| _1|   _2|
    +---+--------------------+---+-----+
    |  1|dsfds dsf dasf ds...|  1|dsfds|
    |  1|dsfds dsf dasf ds...|  1|  dsf|
    |  1|dsfds dsf dasf ds...|  1| dasf|
    |  1|dsfds dsf dasf ds...|  1|  dsf|
    |  1|dsfds dsf dasf ds...|  1|  dsf|
    |  1|dsfds dsf dasf ds...|  1|    d|
    |  2|2344 2353 24 2343...|  2| 2344|
    |  2|2344 2353 24 2343...|  2| 2353|
    |  2|2344 2353 24 2343...|  2|   24|
    |  2|2344 2353 24 2343...|  2|23432|
    |  2|2344 2353 24 2343...|  2|  234|
    +---+--------------------+---+-----+
    

    Si quieres columnas nombradas, se puede definir un caso de la clase para que usted mantenga explotó datos

    scala> :paste
    //Entering paste mode (ctrl-D to finish)
    
    import org.apache.spark.sql.Row
    case class ExplodedData(word: String)
    df.explode(col("id"), col("text")) {case row: Row =>
        val words = row(1).asInstanceOf[String].split(" ")
        words.map(word => ExplodedData(word))
    }
    
    //Exiting paste mode, now interpreting.
    
    import org.apache.spark.sql.Row
    defined class ExplodedData
    res35: org.apache.spark.sql.DataFrame = [id: int, text: string, word: string]
    
    scala> res35.select("id","word").show
    +---+-----+
    | id| word|
    +---+-----+
    |  1|dsfds|
    |  1|  dsf|
    |  1| dasf|
    |  1|  dsf|
    |  1|  dsf|
    |  1|    d|
    |  2| 2344|
    |  2| 2353|
    |  2|   24|
    |  2|23432|
    |  2|  234|
    +---+-----+
    

    Espero que esto trae algunos trasnparencia,.

  2. 0

    Creo que se puede leer más sobre el documento y hacer una prueba primero.

    explotar de un dataframe devolver un dataframe.Y aceptar una función lambda f: (Fila) ⇒ TraversableOnce[a] como parámetro.

    en la función lambda, que coincidirá con la entrada por caso. Usted ya sabe que su entrada será Fila de los empleados, que es todavía un Ss de la Fila.Para el caso de entrada de Fila(empleado: Seq[Fila]) , si usted no entiende esta parte, usted puede aprender una cosa más acerca de la función deshacer en la scala.

    Y que, empleado(yo creo que usted debe utilizar a empleados aquí), como Seq de la Fila, se aplicará la función de mapa a mapa de cada fila a un Empleado. Y usted tendrá que usar el scala aplicar la función para obtener el i-ésimos de valor en esta fila. Pero el valor devuelto es un Objeto , así que hay que utilizar asInstanceOf a convertir en el tipo que esperaba.

Dejar respuesta

Please enter your comment!
Please enter your name here