Извлекать пары ключ-значение из входных данных с помощью Scala, Spark

#scala #apache-spark

#scala #apache-spark

Вопрос:

Данные в файле в виде:

 Maths,K1,A1,K2,A2,K3,A4
Physics,L6,M1,L5,M2,L9,M2
  

Используя Spark и Scala, как я могу извлечь пары ключ-значение как RDD, как показано ниже:

 Maths, K1
Maths, K2
Maths, K3
Physics, L6
Physics, L5
Physics, L9
  

Комментарии:

1. Являются ли входные данные двумя разными списками значений или просто строками? Являются ли A2, A4, M1 … отфильтрованными специально? По каким критериям?

Ответ №1:

Чтобы создать фрейм данных Spark с вашими данными, вы можете действовать следующим образом

 // If the examples were lists of items
val l1 = List("Maths", "K1", "A1", "K2", "A2", "K3", "A4")

// If they were strings, you can proceed like this
val l2 = "Physics,L6,M1,L5,M2,L9,M2".split(",").toSeq 

// toDF() takes a sequence of tuples, which we now can create from our list(s)
val res = l1.tail.map(l1.head -> _).toDF("Subject", "Code")
          .union(l2.tail.map(l2.head -> _).toDF("Subject", "Code"))

// If the filtering in your example was intentional
res.filter("Code not like 'A%' and code not like 'M%'").show

 ------- ---- 
|Subject|Code|
 ------- ---- 
|  Maths|  K1|
|  Maths|  K2|
|  Maths|  K3|
|Physics|  L6|
|Physics|  L5|
|Physics|  L9|
 ------- ---- 
  

Ответ №2:

Предполагая, что мы можем безопасно вывести ожидаемый результат из двух образцов в вашем вопросе, и предполагая, что входные данные представляют собой последовательность строк, вот один из способов его достижения:

 val s = List("Maths,K1,A1,K2,A2,K3,A4","Physics,L6,M1,L5,M2,L9,M2")
val df = s.flatMap(x => {
  val t = x.split(",")
  (1 until t.size by 2).map(t.head -> t(_))
}).toDF("C1", "C2")
  

Результирующий фрейм данных:

  ------- --- 
|     C1| C2|
 ------- --- 
|  Maths| K1|
|  Maths| K2|
|  Maths| K3|
|Physics| L6|
|Physics| L5|
|Physics| L9|
 ------- ---