Extraer valores de columna de Dataframe como Lista en Apache Spark


Me gustaría convertir una columna de cadena de un dataframe a una lista. Lo que puedo encontrar de la API Dataframe es RDD, así que intenté convertirlo de nuevo a RDD primero, y luego aplicar la función toArray al RDD. En este caso, la longitud y SQL funcionan bien. Sin embargo, el resultado que obtuve de RDD tiene corchetes cuadrados alrededor de cada elemento como este [A00001]. Me preguntaba si hay una forma apropiada de convertir una columna en una lista o una forma de eliminar los corchetes.

Cualquier sugerencia sería apreciar. ¡Gracias!

Author: mrsrinivas, 2015-08-14

5 answers

Esto debería devolver la colección que contiene una sola lista:

dataFrame.select("YOUR_COLUMN_NAME").rdd.map(r => r(0)).collect()

Sin la asignación, solo obtiene un objeto Row, que contiene todas las columnas de la base de datos.

Tenga en cuenta que esto probablemente le dará una lista de Cualquier tipo. Ï Si desea especificar el tipo de resultado, puede usarlo .Asinstance of [YOUR_TYPE] in r => r(0).asInstanceOf[YOUR_TYPE] mapping

P.d. debido a la conversión automática, puede omitir la parte .rdd.

 75
Author: Niemand,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-25 06:28:26

Con Spark 2.x y Scala 2.11

Pensaría en 3 formas posibles de convertir valores de una columna específica a la Lista

Fragmentos de código comunes para todos los enfoques

import org.apache.spark.sql.SparkSession

val spark = SparkSession.builder.getOrCreate    
import spark.implicits._ // for .toDf() method

val df = Seq(
    ("first", 2.0),
    ("test", 1.5),
    ("choose", 8.0)
  ).toDF("id", "val")

Enfoque 1

df.select("id").collect().map(_(0)).toList
// res9: List[Any] = List(one, two, three)

¿Qué pasa ahora? Estamos recopilando datos para el Controlador con collect() y recogiendo el elemento cero de cada registro.

Esto no podría ser una excelente manera de hacerlo, Vamos a mejorarlo con el siguiente enfoque.


Enfoque 2

df.select("id").rdd.map(r => r(0)).collect.toList 
//res10: List[Any] = List(one, two, three)

¿Cómo es mejor? Hemos distribuido la carga de transformación de mapas entre los trabajadores en lugar de un solo controlador.

rdd.map(r => r(0)) no te parece elegante. Por lo tanto, vamos a abordar en el siguiente enfoque.


Enfoque 3

df.select("id").map(r => r.getString(0)).collect.toList 
//res11: List[String] = List(one, two, three)

Aquí no estamos convirtiendo DataFrame a RDD. Mira map no aceptará r => r(0) (o _(0)) como el enfoque anterior debido a problemas de codificador en DataFrame. Así que termina usando r => r.getString(0) y se abordaría en el siguiente versiones de Spark.

Conclusión

Todas las opciones dan la misma salida, pero 2 y 3 son eficaces, finalmente 3rd uno es eficaz y elegante(yo creo).

Enlace de cuaderno de Databricks que estará disponible hasta 6 meses a partir del 20/05/2017

 27
Author: mrsrinivas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-14 05:44:43

Sé que la respuesta dada y solicitada se asume para Scala, por lo que solo estoy proporcionando un pequeño fragmento de código Python en caso de que un usuario de PySpark tenga curiosidad. La sintaxis es similar a la respuesta dada, pero para sacar correctamente la lista, en realidad tengo que hacer referencia al nombre de la columna una segunda vez en la función de asignación y no necesito la instrucción select.

Es decir, un DataFrame, que contiene una columna llamada " Raw "

Para obtener cada valor de fila en " Raw " combinado como una lista donde cada entrada es un valor de fila de " Raw " simplemente uso:

MyDataFrame.rdd.map(lambda x: x.Raw).collect()
 10
Author: abby sobh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-30 23:41:23

En Scala y Spark 2+, prueba esto (asumiendo que el nombre de tu columna es " s"): df.select('s).as[String].collect

 3
Author: kanielc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-10 17:20:14
     sqlContext.sql(" select filename from tempTable").rdd.map(r => r(0)).collect.toList.foreach(out_streamfn.println) //remove brackets

Funciona perfectamente

 0
Author: Shaina Raza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-16 05:58:49