Подтвердить что ты не робот

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

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

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

4b9b3361

Ответ 1

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

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

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

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

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

Ответ 2

С 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) и это будет r => r.getString(0) в следующих версиях Spark.

Заключение

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

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

Ответ 3

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

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

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

MyDataFrame.rdd.map(lambda x: x.Raw).collect()

Ответ 4

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

Ответ 5

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

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