【问题标题】:Replace value in deep nested schema Spark Dataframe替换深层嵌套模式 Spark Dataframe 中的值
【发布时间】:2020-04-01 21:52:07
【问题描述】:

我是 pyspark 的新手。我试图了解如何使用多层嵌套结构和数组访问镶木地板文件。我需要用 null 替换数据帧(带有嵌套模式)中的一些值,我已经看到这个 solution 它适用于结构,但不确定它如何适用于数组。

我的架构是这样的

|-- unitOfMeasure: struct
|    |-- raw: struct
|    |    |-- id: string
|    |    |-- codingSystemId: string
|    |    |-- display: string
|    |-- standard: struct
|    |    |-- id: string
|    |    |-- codingSystemId: string
|-- Id: string
|-- actions: array
|    |-- element: struct
|    |    |-- action: string
|    |    |-- actionDate: string
|    |    |-- actor: struct
|    |    |    |-- actorId: string
|    |    |    |-- aliases: array
|    |    |    |    |-- element: struct
|    |    |    |    |    |-- value: string
|    |    |    |    |    |-- type: string
|    |    |    |    |    |-- assigningAuthority: string
|    |    |    |-- fullName: string

我想要做的是将 unitOfMeasure.raw.id 替换为 null 和actions.element.action 为空 和 actions.element.actor.aliases.element.value 与 null 保持我的数据框的其余部分保持不变。

有什么方法可以实现吗?

【问题讨论】:

    标签: apache-spark pyspark apache-spark-sql pyspark-sql


    【解决方案1】:

    对于数组列,与结构字段相比,它有点复杂。 一种选择是将数组分解为新列,以便您可以访问和更新嵌套结构。更新后,您必须重建初始数组列。

    但我更喜欢使用为 Spark >=2.4 引入的高阶函数 transform 这是一个示例:

    输入 DF:

     |-- actions: array (nullable = true)
     |    |-- element: struct (containsNull = true)
     |    |    |-- action: string (nullable = true)
     |    |    |-- actionDate: string (nullable = true)
     |    |    |-- actor: struct (nullable = true)
     |    |    |    |-- actorId: long (nullable = true)
     |    |    |    |-- aliases: array (nullable = true)
     |    |    |    |    |-- element: struct (containsNull = true)
     |    |    |    |    |    |-- assigningAuthority: string (nullable = true)
     |    |    |    |    |    |-- type: string (nullable = true)
     |    |    |    |    |    |-- value: string (nullable = true)
     |    |    |    |-- fullName: string (nullable = true)
    
    +--------------------------------------------------------------+
    |actions                                                       |
    +--------------------------------------------------------------+
    |[[action_name1, 2019-12-08, [2, [[aa, t1, v1]], full_name1]]] |
    |[[action_name2, 2019-12-09, [3, [[aaa, t2, v2]], full_name2]]]|
    +--------------------------------------------------------------+
    

    我们将一个 lambda 函数传递给transfrom,它选择所有结构字段并将actions.actionactions.actor.aliases.value 替换为null

    transform_expr = """transform (actions, x -> 
                                   struct(null as action, 
                                          x.actionDate as actionDate, 
                                          struct(x.actor.actorId as actorId, 
                                                 transform(x.actor.aliases, y -> 
                                                           struct(null as value, 
                                                                  y.type as type, 
                                                                  y.assigningAuthority as assigningAuthority)
                                                           ) as aliases,
                                                x.actor.fullName as fullName
                                          ) as actor
                                    ))"""
    
    df.withColumn("actions", expr(transform_expr)).show(truncate=False)
    

    输出DF:

    +------------------------------------------------+
    |actions                                         |
    +------------------------------------------------+
    |[[, 2019-12-08, [2, [[, t1, aa]], full_name1]]] |
    |[[, 2019-12-09, [3, [[, t2, aaa]], full_name2]]]|
    +------------------------------------------------+
    

    【讨论】:

      猜你喜欢
      • 2019-07-07
      • 2018-10-29
      • 1970-01-01
      • 2020-12-02
      • 2016-01-27
      • 2020-04-07
      • 2021-07-16
      • 1970-01-01
      • 2020-06-15
      相关资源
      最近更新 更多