как денормализовать данные на фрейме - PullRequest
0 голосов
/ 26 апреля 2018

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

Исходный кадр данных: Key, item_desc

Целевой фрейм данных: Key, item_desc1, item_desc2, item_desc3, item_desc4

для каждых 4 записей в исходном фрейме данных я должен создать одну запись в целевом фрейме данных.

исходные данные:

Key, item_desc
1, desc1
1, desc2
1, desc3
1, desc4
1, desc5
1, desc6

целевые данные:

key, item_desc1, item_desc2, item_desc3, item_desc4
1, desc1, desc2, desc3, desc4
1, desc5, desc6

Может кто-нибудь подсказать мне, как написать этот код? Я сделал пример кода, чтобы сделать это на Scala, как показано ниже:

var l = (1 to 102).toList
var n = ""
var j = 1
for (i <- l){
n = n + l(j) + ","
if (j%4 == 0) {
println(n)
n = ""
}
if (j+1 == l.size) println(n)
j = j+1
}

Но я должен применить эту логику к фрейму данных / rdd / list.

Пожалуйста, помогите мне в этом!

1 Ответ

0 голосов
/ 26 апреля 2018

Вы можете попробовать что-то вроде этого:

import org.apache.spark.sql.expressions._
import org.apache.spark.sql.functions._

val w = Window.partitionBy("key").orderBy("item_desc")

val df = Seq(
  (1, "desc1"), (1, "desc2"), (1, "desc3"), 
  (1, "desc4"), (1, "desc5"), (1, "desc6")
).toDF("key", "item_desc")

df
  // Add sequential id for group 0 .. n - 1
  .withColumn("id", row_number.over(w) - 1)
  // Add row group id
  .withColumn("group_id", floor($"id" / 4))
  // Add column group id 
  .withColumn("column_id", concat(lit("item_desc"), $"id" % 4))
  .groupBy("key", "group_id")
  .pivot("column_id")
  .agg(first("item_desc"))
  .drop("group_id").show
// +---+----------+----------+----------+----------+
// |key|item_desc0|item_desc1|item_desc2|item_desc3|
// +---+----------+----------+----------+----------+
// |  1|     desc1|     desc2|     desc3|     desc4|
// |  1|     desc5|     desc6|      null|      null|
// +---+----------+----------+----------+----------+

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

...