Quero converter uma coluna de string de um quadro de dados em uma lista. O que posso encontrar na Dataframe
API é RDD, então tentei primeiro convertê-lo de volta para RDD e depois aplicar a toArray
função ao RDD. Nesse caso, o comprimento e o SQL funcionam perfeitamente. No entanto, o resultado que obtive do RDD tem colchetes em torno de cada elemento como este [A00001]
. Eu queria saber se existe uma maneira apropriada de converter uma coluna em uma lista ou uma maneira de remover os colchetes.
Qualquer sugestão seria apreciada. Obrigado!
Respostas:
Isso deve retornar a coleção contendo uma lista única:
dataFrame.select("YOUR_COLUMN_NAME").rdd.map(r => r(0)).collect()
Sem o mapeamento, você obtém apenas um objeto Row, que contém todas as colunas do banco de dados.
Lembre-se de que isso provavelmente resultará em uma lista de qualquer tipo. Se você quiser especificar o tipo de resultado, você pode usar .asInstanceOf [YOUR_TYPE] no
r => r(0).asInstanceOf[YOUR_TYPE]
mapeamentoPS devido à conversão automática, você pode pular a
.rdd
parte.fonte
collect().map(r => r(0))
- esta ordem tem alguma desvantagem?Com Spark 2.xe Scala 2.11
Eu pensaria em três maneiras possíveis de converter valores de uma coluna específica em Lista.
Snippets de código comuns para todas as abordagens
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")
Abordagem 1
df.select("id").collect().map(_(0)).toList // res9: List[Any] = List(one, two, three)
O que acontece agora? Estamos coletando dados para o Driver
collect()
e escolhendo o elemento zero de cada registro.Essa não poderia ser uma maneira excelente de fazer isso. Vamos melhorá-la na próxima abordagem.
Abordagem 2
df.select("id").rdd.map(r => r(0)).collect.toList //res10: List[Any] = List(one, two, three)
Como está melhor? Distribuímos a carga de transformação do mapa entre os trabalhadores, em vez de um único driver.
Eu sei
rdd.map(r => r(0))
que não parece elegante você. Então, vamos abordar isso na próxima abordagem.Abordagem 3
df.select("id").map(r => r.getString(0)).collect.toList //res11: List[String] = List(one, two, three)
Aqui não estamos convertendo DataFrame em RDD. Observe
map
que não aceitar => r(0)
(ou_(0)
) como a abordagem anterior devido a problemas de codificador no DataFrame. Então acabe usandor => r.getString(0)
e seria abordado nas próximas versões do Spark.Todas as opções dão a mesma saída, mas 2 e 3 são eficazes, finalmente o terceiro é eficaz e elegante (eu acho).
Caderno Databricks
fonte
Eu sei que a resposta dada e solicitada é presumida para Scala, então estou apenas fornecendo um pequeno trecho de código Python no caso de um usuário PySpark estar curioso. A sintaxe é semelhante à resposta fornecida, mas para abrir a lista corretamente, na verdade, preciso fazer referência ao nome da coluna uma segunda vez na função de mapeamento e não preciso da instrução select.
ou seja, um DataFrame, contendo uma coluna chamada "Raw"
Para obter cada valor de linha em "Raw" combinado como uma lista em que cada entrada é um valor de linha de "Raw", simplesmente uso:
MyDataFrame.rdd.map(lambda x: x.Raw).collect()
fonte
No Scala e no Spark 2+, tente isso (assumindo que o nome da coluna seja "s"):
df.select('s).as[String].collect
fonte
sqlContext.sql(" select filename from tempTable").rdd.map(r => r(0)).collect.toList.foreach(out_streamfn.println) //remove brackets
funciona perfeitamente
fonte
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
Já que ninguém deu nenhuma solução em java (Real Programming Language) Pode me agradecer depois
fonte
from pyspark.sql.functions import col df.select(col("column_name")).collect()
aqui, coletar são funções que, por sua vez, o convertem em lista. Cuidado ao usar a lista do enorme conjunto de dados. Isso diminuirá o desempenho. É bom verificar os dados.
fonte
Esta é a resposta java.
df.select("id").collectAsList();
fonte
Uma solução atualizada que fornece uma lista:
dataFrame.select("YOUR_COLUMN_NAME").map(r => r.getString(0)).collect.toList
fonte