Как читать из файла CSV, чтобы создать объект карты Scala? - PullRequest
0 голосов
/ 03 июля 2019

У меня есть путь к CSV, с которого я хотел бы прочитать.Этот CSV включает в себя три столбца: «тема, ключ, значение» Я использую спарк, чтобы прочитать этот файл как CSV-файл.Файл выглядит следующим образом (lookupFile.csv):

Topic,Key,Value
fruit,aaa,apple
fruit,bbb,orange
animal,ccc,cat
animal,ddd,dog

//I'm reading the file as follows
val lookup = SparkSession.read.option("delimeter", ",").option("header", "true").csv(lookupFile)

Я хотел бы взять то, что я только что прочитал, и вернуть карту со следующими свойствами:

  • Карта использует тему в качестве ключа
  • Значением этой карты является карта столбцов «Ключ» и «Значение»

Я надеюсь, что получу картуэто выглядит следующим образом:

val result = Map("fruit" -> Map("aaa" -> "apple", "bbb" -> "orange"),
                 "animal" -> Map("ccc" -> "cat", "ddd" -> "dog"))

Есть идеи, как мне это сделать?

Ответы [ 2 ]

1 голос
/ 03 июля 2019
scala> val in = spark.read.option("header", true).option("inferSchema", true).csv("""Topic,Key,Value
     | fruit,aaa,apple
     | fruit,bbb,orange
     | animal,ccc,cat
     | animal,ddd,dog""".split("\n").toSeq.toDS)
in: org.apache.spark.sql.DataFrame = [Topic: string, Key: string ... 1 more field]

scala> val res = in.groupBy('Topic).agg(map_from_entries(collect_list(struct('Key, 'Value))).as("subMap"))
res: org.apache.spark.sql.DataFrame = [Topic: string, subMap: map<string,string>]

scala> val scalaMap = res.collect.map{
     | case org.apache.spark.sql.Row(k : String, v : Map[String, String]) => (k, v) 
     | }.toMap
<console>:26: warning: non-variable type argument String in type pattern scala.collection.immutable.Map[String,String] (the underlying of Map[String,String]) is unchecked since it is eliminated by erasure
       case org.apache.spark.sql.Row(k : String, v : Map[String, String]) => (k, v)
                                                     ^
scalaMap: scala.collection.immutable.Map[String,Map[String,String]] = Map(animal -> Map(ccc -> cat, ddd -> dog), fruit -> Map(aaa -> apple, bbb -> orange))
0 голосов
/ 03 июля 2019

прочитайте ваши данные

val df1= spark.read.format("csv").option("inferSchema", "true").option("header", "true").load(path)

сначала вставьте "ключ, значение" в разделы array и groupBy, чтобы разделить цель на ключевую часть и часть значения.

val df2= df.groupBy("Topic").agg(collect_list(array($"Key",$"Value")).as("arr"))

теперь преобразуйте в набор данных

val ds= df2.as[(String,Seq[Seq[String]])]

примените логику к полям, чтобы получить карту карт и собрать

val ds1 =ds.map(x=> (x._1,x._2.map(y=> (y(0),y(1))).toMap)).collect

теперь ваши данные настроены с темой в качестве ключа и«ключ, значение» в качестве значения, так что теперь примените карту, чтобы получить ваш результат

ds1.toMap

Map(animal -> Map(ccc -> cat, ddd -> dog), fruit -> Map(aaa -> apple, bbb -> orange))
...