替换深度嵌套模式Scala Spark Dataframe中的值

时间:2019-02-13 23:35:29

标签: scala apache-spark dataframe schema

我需要用null替换数据帧(具有嵌套模式)中的某些值,我已经看到了这个solution,但似乎只适用于一个  级别的嵌套模式。

我的模式是这样的

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.leveluser.state.xp替换为null,并保持其余数据框不变。

有什么办法可以做到这一点?

如果我关注this solution

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 :(得分:0)

基于评论中我使用过this link的@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)