преобразовать строковое значение в карту, используя scala - PullRequest
0 голосов
/ 21 марта 2019

У меня есть файл CSV с одним из полей с картой, как указано ниже «Карта (12345 -> 45678, 23465 -> 9876)»

Когда я пытаюсь загрузить CSV в dataframe, он рассматривает его как строку. Итак, я написал UDF для преобразования строки в карту, как показано ниже

 val convertToMap = udf((pMap: String) => { 
   val mpp = pMap
   // "Map(12345 -> 45678, 23465 -> 9876)" 
   val stg = mpp.substr(4, mpp.length() -1) val stg1=stg.split(regex=",").toList       
   val mp=stg1.map(_.split(regex=" ").toList) 
   val mp1 = mp.map(mp =>
   (mp(0), mp(2))).toMap 
   } )

Теперь мне нужна помощь в применении UDF к столбцу, где он принимается как строка, и возвращение DF с преобразованным столбцом.

1 Ответ

1 голос
/ 21 марта 2019

Вы довольно близки, но похоже, что ваш UDF имеет некоторую смесь scala и python, и логика синтаксического анализа требует небольшой работы.Может быть лучший способ для анализа строки литерала карты, но это работает с предоставленным примером:

val convertToMap = udf { (pMap: String) =>
  val stg = pMap.substring(4, pMap.length() - 1)
  val stg1 = stg.split(",").toList.map(_.trim)
  val mp = stg1.map(_.split(" ").toList) 
  mp.map(mp =>(mp(0), mp(2))).toMap 
}

val df = spark.createDataset(Seq("Map(12345 -> 45678, 23465 -> 9876)")).toDF("strMap")

С исправленным UDF вы просто вызываете его с помощью .select() или .withColumn():

df.select(convertToMap($"strMap").as("map")).show(false)

Что дает:

+----------------------------------+
|map                               |
+----------------------------------+
|Map(12345 -> 45678, 23465 -> 9876)|
+----------------------------------+

Со схемой:

root
 |-- map: map (nullable = true)
 |    |-- key: string
 |    |-- value: string (valueContainsNull = true)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...