Я хочу преобразовать строковый столбец фрейма данных в список. В Dataframe
API я могу найти RDD, поэтому я попытался сначала преобразовать его обратно в RDD, а затем применить toArray
функцию к RDD. В этом случае длина и SQL работают нормально. Однако результат, который я получил от RDD, заключен в квадратные скобки вокруг каждого такого элемента [A00001]
. Мне было интересно, есть ли подходящий способ преобразовать столбец в список или способ удалить квадратные скобки.
Мы ценим любые предложения. Спасибо!
scala
apache-spark
apache-spark-sql
ЗАСТЕНЧИВЫЙ.
источник
источник
Ответы:
Это должно вернуть коллекцию, содержащую единственный список:
dataFrame.select("YOUR_COLUMN_NAME").rdd.map(r => r(0)).collect()
Без сопоставления вы просто получите объект Row, который содержит все столбцы из базы данных.
Имейте в виду, что это, вероятно, даст вам список любого типа. ÏЕсли вы хотите указать тип результата, вы можете использовать .asInstanceOf [YOUR_TYPE] в
r => r(0).asInstanceOf[YOUR_TYPE]
сопоставленииPS из-за автоматической конвертации можно пропустить
.rdd
часть.источник
collect().map(r => r(0))
- есть ли у этого порядка недостатки?В 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)
Что происходит сейчас? Мы собираем данные для драйвера
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 эффективны, наконец, 3-й эффективен и элегантен (я думаю).
Блокнот Databricks
источник
Я знаю, что данный и запрошенный ответ предполагается для Scala, поэтому я просто предоставляю небольшой фрагмент кода Python на тот случай, если пользователю PySpark интересно. Синтаксис аналогичен данному ответу, но для правильного отображения списка мне действительно нужно ссылаться на имя столбца во второй раз в функции сопоставления, и мне не нужен оператор select.
т.е. DataFrame, содержащий столбец с именем "Raw"
Чтобы получить каждое значение строки в "Raw", объединенное в список, где каждая запись является значением строки из "Raw", я просто использую:
MyDataFrame.rdd.map(lambda x: x.Raw).collect()
источник
В Scala и Spark 2+ попробуйте следующее (при условии, что имя вашего столбца - «s»):
df.select('s).as[String].collect
источник
sqlContext.sql(" select filename from tempTable").rdd.map(r => r(0)).collect.toList.foreach(out_streamfn.println) //remove brackets
это работает отлично
источник
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
Поскольку никто не дал никакого решения на java (настоящий язык программирования), можете поблагодарить меня позже
источник
from pyspark.sql.functions import col df.select(col("column_name")).collect()
здесь collect - это функции, которые, в свою очередь, преобразуют его в список. Остерегайтесь использовать список на огромном наборе данных. Это снизит производительность. Хорошо бы проверить данные.
источник
Это ответ Java.
df.select("id").collectAsList();
источник
Обновленное решение со списком:
dataFrame.select("YOUR_COLUMN_NAME").map(r => r.getString(0)).collect.toList
источник