Quiero convertir una columna de cadena de un marco de datos en una lista. Lo que puedo encontrar en la Dataframe
API es RDD, así que primero intenté convertirlo a RDD y luego apliqué la toArray
función al RDD. En este caso, la longitud y SQL funcionan bien. Sin embargo, el resultado que obtuve de RDD tiene corchetes alrededor de cada elemento como este [A00001]
. Me preguntaba si hay una forma adecuada de convertir una columna en una lista o una forma de eliminar los corchetes.
Cualquier sugerencia sera apreciada. ¡Gracias!
Respuestas:
Esto debería devolver la colección que contiene una lista única:
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 usar .asInstanceOf [YOUR_TYPE] en la
r => r(0).asInstanceOf[YOUR_TYPE]
asignaciónPD: debido a la conversión automática, puede omitir la
.rdd
parte.fuente
collect().map(r => r(0))
: ¿este orden tiene alguna desventaja?Con Spark 2.xy Scala 2.11
Pensaría en 3 formas posibles de convertir valores de una columna específica en List.
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)
¿Que pasa ahora? Estamos recopilando datos para Driver
collect()
y seleccionando el elemento cero de cada registro.Esta no podría ser una excelente manera de hacerlo, mejorémosla 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.
Sé que
rdd.map(r => r(0))
no te parece elegante. Entonces, abordemos esto 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. Mire
map
que no aceptarár => r(0)
(o_(0)
) como el enfoque anterior debido a problemas del codificador en DataFrame. Así que termine usándolor => r.getString(0)
y se abordará en las próximas versiones de Spark.Todas las opciones dan el mismo resultado, pero 2 y 3 son efectivas, finalmente la tercera es efectiva y elegante (creo).
Cuaderno de Databricks
fuente
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 la lista correctamente, en realidad tengo que hacer referencia al nombre de la columna por segunda vez en la función de mapeo y no necesito la declaración de selección.
es decir, un DataFrame, que contiene una columna denominada "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()
fuente
En Scala y Spark 2+, intente esto (asumiendo que el nombre de su columna es "s"):
df.select('s).as[String].collect
fuente
sqlContext.sql(" select filename from tempTable").rdd.map(r => r(0)).collect.toList.foreach(out_streamfn.println) //remove brackets
funciona perfectamente
fuente
List<String> whatever_list = df.toJavaRDD().map(new Function<Row, String>() { public String call(Row row) { return row.getAs("column_name").toString(); } }).collect(); logger.info(String.format("list is %s",whatever_list)); //verification
Como nadie ha dado ninguna solución en java (Real Programming Language), puede agradecerme más tarde
fuente
from pyspark.sql.functions import col df.select(col("column_name")).collect()
aquí se recopilan funciones que a su vez lo convierten en lista. Tenga cuidado de utilizar la lista en el enorme conjunto de datos. Disminuirá el rendimiento. Es bueno verificar los datos.
fuente
Esta es la respuesta de Java.
df.select("id").collectAsList();
fuente
Una solución actualizada que le ofrece una lista:
dataFrame.select("YOUR_COLUMN_NAME").map(r => r.getString(0)).collect.toList
fuente