Chcę przekonwertować kolumnę z ciągiem ramki danych na listę. To, co mogę znaleźć w Dataframe
API, to RDD, więc najpierw próbowałem przekonwertować go z powrotem na RDD, a następnie zastosować toArray
funkcję do RDD. W takim przypadku długość i SQL działają dobrze. Jednak wynik, który otrzymałem z RDD, ma nawiasy kwadratowe wokół każdego takiego elementu [A00001]
. Zastanawiałem się, czy istnieje odpowiedni sposób przekonwertowania kolumny na listę lub sposób na usunięcie nawiasów kwadratowych.
Wszelkie sugestie będą mile widziane. Dziękuję Ci!
Odpowiedzi:
Powinno to zwrócić zbiór zawierający jedną listę:
dataFrame.select("YOUR_COLUMN_NAME").rdd.map(r => r(0)).collect()
Bez mapowania otrzymujesz po prostu obiekt Row, który zawiera każdą kolumnę z bazy danych.
Pamiętaj, że prawdopodobnie dostaniesz listę dowolnego typu. ÏJeśli chcesz określić typ wyniku, możesz użyć .asInstanceOf [YOUR_TYPE] w
r => r(0).asInstanceOf[YOUR_TYPE]
mapowaniuPS dzięki automatycznej konwersji możesz pominąć
.rdd
część.źródło
collect().map(r => r(0))
- czy ta kolejność ma jakieś wady?Z Spark 2.x i Scala 2.11
Wymyśliłbym 3 możliwe sposoby konwersji wartości określonej kolumny na Listę.
Wspólne fragmenty kodu dla wszystkich podejść
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")
Podejście 1
df.select("id").collect().map(_(0)).toList // res9: List[Any] = List(one, two, three)
Co się teraz stanie? Zbieramy dane do Kierowcy
collect()
i wybieramy element zerowy z każdego rekordu.To nie może być doskonały sposób na zrobienie tego. Poprawmy to następnym podejściem.
Podejście 2
df.select("id").rdd.map(r => r(0)).collect.toList //res10: List[Any] = List(one, two, three)
Jak to jest lepsze? Rozłożyliśmy obciążenie związane z transformacją mapy na pracowników, a nie na jednego kierowcę.
Wiem,
rdd.map(r => r(0))
że nie wydaje ci się elegancka. Więc zajmijmy się tym w następnym podejściu.Podejście 3
df.select("id").map(r => r.getString(0)).collect.toList //res11: List[String] = List(one, two, three)
Tutaj nie konwertujemy DataFrame na RDD. Spójrz na
map
to, że nie zaakceptujer => r(0)
(lub_(0)
) jak poprzednie podejście z powodu problemów z koderem w DataFrame. Skończ więc z używaniemr => r.getString(0)
i zostanie to rozwiązane w następnych wersjach Spark.Wszystkie opcje dają taką samą wydajność, ale 2 i 3 są efektywne, w końcu trzecia jest skuteczna i elegancka (tak mi się wydaje).
Notatnik Databricks
źródło
Wiem, że odpowiedź udzielona i poproszona jest założona dla Scala, więc podaję tylko mały fragment kodu Pythona na wypadek, gdyby użytkownik PySpark był ciekawy. Składnia jest podobna do podanej odpowiedzi, ale aby poprawnie wyświetlić listę, muszę odwołać się do nazwy kolumny po raz drugi w funkcji mapowania i nie potrzebuję instrukcji select.
tj. DataFrame, zawierająca kolumnę o nazwie „Raw”
Aby uzyskać wartość każdego wiersza w „Raw” połączoną jako listę, gdzie każdy wpis jest wartością wiersza z „Raw”, po prostu używam:
MyDataFrame.rdd.map(lambda x: x.Raw).collect()
źródło
W Scali i Spark 2+ spróbuj tego (zakładając, że nazwa Twojej kolumny to „s”):
df.select('s).as[String].collect
źródło
sqlContext.sql(" select filename from tempTable").rdd.map(r => r(0)).collect.toList.foreach(out_streamfn.println) //remove brackets
działa idealnie
źródło
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
Ponieważ nikt nie podał żadnego rozwiązania w java (prawdziwy język programowania), możesz mi później podziękować
źródło
from pyspark.sql.functions import col df.select(col("column_name")).collect()
tutaj collect to funkcje, które z kolei konwertują je na listę. Uważaj na korzystanie z listy w ogromnym zbiorze danych. Spowoduje to obniżenie wydajności. Warto sprawdzić dane.
źródło
To jest odpowiedź Java.
df.select("id").collectAsList();
źródło
Zaktualizowane rozwiązanie, które zawiera listę:
dataFrame.select("YOUR_COLUMN_NAME").map(r => r.getString(0)).collect.toList
źródło