代码之家  ›  专栏  ›  技术社区  ›  Am1rr3zA

深嵌套模式中的scala spark替换值

  •  0
  • Am1rr3zA  · 技术社区  · 6 年前

    我需要用 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.level user.state.xp 具有 无效的 保持我的数据帧的其他部分不变。

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

    如果我跟随 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

    0 回复  |  直到 6 年前
        1
  •  0
  •   Am1rr3zA    6 年前

    基于我使用的注释中的@auprba链接 this link 提出了这个解决方案。

    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)