it-roy-ru.com

Извлечь значения столбца Dataframe в виде списка в Apache Spark

Я хотел бы преобразовать строковый столбец данных в список. В API Dataframe я могу найти RDD, поэтому я попытался сначала преобразовать его в RDD, а затем применить функцию toArray к RDD. В этом случае длина и SQL работают просто отлично. Тем не менее, результат, который я получил от RDD, имеет квадратные скобки вокруг каждого элемента, такого как [A00001]. Мне было интересно, если есть подходящий способ преобразовать столбец в список или способ убрать квадратные скобки.

Мы ценим любые предложения. Спасибо!

60
SH Y.

Это должно вернуть коллекцию, содержащую один список:

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

Без отображения вы просто получаете объект Row, который содержит каждый столбец из базы данных.

Имейте в виду, что это, вероятно, даст вам список любого типа. Если вы хотите указать тип результата, вы можете использовать .asInstanceOf [YOUR_TYPE] в отображении r => r(0).asInstanceOf[YOUR_TYPE]

Постскриптум из-за автоматического преобразования вы можете пропустить часть .rdd.

81
Niemand

С Spark 2.x и Scala 2.11

Я думаю о 3 возможных способах преобразования значений определенного столбца в список

Общие фрагменты кода для всех подходов

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")

Подход 1

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

Что происходит сейчас? Мы собираем данные в Driver с помощью collect() и выбираем нулевой элемент из каждой записи. 

Это не может быть отличным способом сделать это, давайте улучшим его следующим подходом.


Подход 2

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

Как это лучше? Мы распределили нагрузку преобразования карты среди рабочих, а не по одному драйверу. 

Я знаю, что rdd.map(r => r(0)) не выглядит элегантно для вас. Итак, давайте рассмотрим это в следующем подходе.


Подход 3

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

Здесь мы не конвертируем DataFrame в RDD. Посмотрите на map, он не примет r => r(0) (или _(0)) как предыдущий подход из-за проблем с кодировщиком в DataFrame. Поэтому в конечном итоге используйте r => r.getString(0), и это будет решено в следующих версиях Spark.

Заключение

Все опции дают одинаковый результат, но 2 и 3 эффективны, наконец, третий - эффективный и элегантный (я думаю, что).

ссылка на блокнот Databricks, которая будет доступна до 6 месяцев с 2017/05/20

34
mrsrinivas

Я знаю, что ответ, который был задан и запрошен, предполагается для Scala, поэтому я просто предоставляю небольшой фрагмент кода Python на случай, если пользователю PySpark будет любопытно. Синтаксис аналогичен приведенному ответу, но чтобы правильно вывести список из списка, мне нужно во второй раз ссылаться на имя столбца в функции отображения, и мне не нужен оператор select.

т.е. DataFrame, содержащий столбец с именем «Raw»

Чтобы получить каждое значение строки в «Raw», объединенное в список, где каждая запись является значением строки из «Raw», я просто использую:

MyDataFrame.rdd.map(lambda x: x.Raw).collect()
14
abby sobh

В Scala и Spark 2+ попробуйте следующее (при условии, что имя вашего столбца - "s"): df.select('s).as[String].collect

4
kanielc
     sqlContext.sql(" select filename from tempTable").rdd.map(r => r(0)).collect.toList.foreach(out_streamfn.println) //remove brackets

это отлично работает

0
Shaina Raza