Создать Spark Row на карте

3

Я видел учебник по Dataframes по адресу https://databricks.com/blog/2015/02/17/introduction-dataframes-in-spark-for-large-scale-data-science.html, который написан на Python. Я пытаюсь перевести это на Scala.

У них есть следующий код:

df = context.load("/path/to/people.json")
# RDD-style methods such as map, flatMap are available on DataFrames
# Split the bio text into multiple words.
words = df.select("bio").flatMap(lambda row: row.bio.split(" "))
# Create a new DataFrame to count the number of words
words_df = words.map(lambda w: Row(word=w, cnt=1)).toDF()
word_counts = words_df.groupBy("word").sum()

Итак, я сначала читаю данные из csv в df а затем получаю:

val title_words = df.select("title").flatMap { row =>    
  row.getAs[String("title").split(" ") }
val title_words_df = title_words.map( w => Row(w,1) ).toDF()
val word_counts = title_words_df.groupBy("word").sum()

но я не знаю

  1. как назначить имена полей для строк в строке, начинающейся с val title_words_df =...

  2. У меня ошибка "Значение toDF не является членом org.apache.spark.rdd.RDD [org.apache.spark.sql.Row]"

Заранее спасибо за помощь.

Теги:
apache-spark
apache-spark-sql
spark-dataframe

1 ответ

2

как назначить имена полей строкам

Python Row - это совсем другой тип объекта, чем его аналог Scala. Это кортеж, дополненный именами, которые делают его более похожим на тип продукта, чем нетипизированная коллекция (o.a.s.sql.Row).

У меня есть ошибка "Значение toDF не является членом org.apache.spark.rdd.RDD [org.apache.spark.sql.Row]"

Так как o.a.s.sql.Row в основном нетипизирован, он не может использоваться с toDF и требует createDataFrame с явной схемой.

import org.apache.spark.sql.types._

val schema = StructType(Seq(
  StructField("word", StringType), StructField("cnt", LongType)
))

sqlContext.createDataFrame(title_words.map(w => Row(w, 1L)), schema)

Если вы хотите, чтобы ваш код был эквивалентен версии Python, вы должны использовать типы продуктов вместо Row. Это означает либо Tuple:

title_words.map((_, 1L)).toDF("word", "cnt")

или класс case:

case class Record(word: String, cnt: Long)

title_words.map(Record(_, 1L)).toDF

На практике, однако, не должно быть необходимости использовать RDD:

import org.apache.spark.sql.functions.{explode, lit, split}

df.select(explode(split($"title", " ")), lit(1L))

Ещё вопросы

Сообщество Overcoder
Наверх
Меню