Заменить значение в глубоко вложенной схеме Scala Spark Dataframe - PullRequest
0 голосов
/ 14 февраля 2019

Мне нужно заменить некоторое значение во фрейме данных (с вложенной схемой) на null, я видел это решение , но кажется, что оно работает только для вложенной схемы одного уровня.

Моя схема выглядит примерно так

root 
 ......
 ......
 ......
 |-- user: struct (nullable = true)
 |    |-- country: string (nullable = true)
 |    |-- id: string (nullable = true)
 |    |-- ip_address: string (nullable = true)
 |    |-- state: struct (nullable = true) 
 |    |    |-- level: long (nullable = true)
 |    |    |-- session_id: string (nullable = true) 
 |    |    |-- xp: long (nullable = true)

Я хотел бы заменить user.state.level и user.state.xp на null и оставить остальную часть моего фрейма данных нетронутой.

Есть ли способ, которым я могу достичь этого?

Если я буду следовать этому решению

val myUDF = udf((s:String) => {
    null
})

val structCols: Array[org.apache.spark.sql.Column] = badVersion.select($"user.*")
    .columns
    .map(name => col("user."+name))

val newDF = badVersion.withColumn(
    "user",
    struct((structCols:+myUDF($"user.country").as("country")):_*)
)

Это работает для страны и заменяет значение, но если ясделать это для

val newDF = badVersion.withColumn(
    "user",
    struct((structCols:+myUDF($"user.country").as("country"):+myUDF($"user.state.level").as("state.level")):_*)
)

Просто добавим state.level в качестве нового поля

enter image description here

1 Ответ

0 голосов
/ 14 февраля 2019

На основании ссылки @Auprba в комментарии я использовал эту ссылку и придумал это решение.

val replaced = df.selectExpr("""
    named_struct(
         .....................................................
         ....... Other columns ...............................
         ....... In a form of  ...............................
         ....... '{columnname}', {columnname}, ...............
         .....................................................
        'user', named_struct(
          'country', user.country,
          'id', user.id,
          'ip_address', user.ip_address,
          'state', named_struct('hard_currency', null, 'level', null, 'session_id', user.state.session_id, 'soft_currency', null, 'xp', null)
        )
    ) as named_struct
""").select("named_struct.*")
display(replaced)
...