【问题标题】:How to update a value in an array of structs in a dataframe in pyspark?如何在pyspark的数据框中更新结构数组中的值?
【发布时间】:2021-12-22 21:52:42
【问题描述】:

我有以下架构:

>>> df.printSchema()
root
... SNIP ...
 |-- foo: array (nullable = true)
 |    |-- element: struct (containsNull = true)
... SNIP ...
 |    |    |-- value: double (nullable = true)
 |    |    |-- value2: double (nullable = true)

在这种情况下,我在数据框和 foo 数组中只有一行:

>>> df.count()
1
>>> df.select(explode('foo').alias("fooColumn")).count()
1

value 为空:

>>> df.select(explode('foo').alias("fooColumn")).select('fooColumn.value','fooColumn.value2').show()
+-----+------+
|value|value2|
+-----+------+
| null|  null|
+-----+------+

我想编辑value 并创建一个新的数据框。我可以爆foo并设置value

>>> fooUpdated = df.select(explode("foo").alias("fooColumn")).select("fooColumn.*").withColumn('value', lit(10)).select('value').show()
+-----+
|value|
+-----+
|   10|
+-----+

如何折叠此数据框以将 fooUpdated 作为带有 struct 元素的数组重新放入,或者有没有办法在不爆炸 foo 的情况下做到这一点?

最后,我想要以下:

>>> dfUpdated.select(explode('foo').alias("fooColumn")).select('fooColumn.value', 'fooColumn.value2').show()
+-----+------+
|value|value2|
+-----+------+
|   10|  null|
+-----+------+

【问题讨论】:

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


    【解决方案1】:

    您可以使用transform 函数更新foo 数组中的每个结构。

    这是一个例子:

    import pyspark.sql.functions as F
    
    df.printSchema()
    
    #root
    # |-- foo: array (nullable = true)
    # |    |-- element: struct (containsNull = true)
    # |    |    |-- value: string (nullable = true)
    # |    |    |-- value2: long (nullable = true)
    
    df1 = df.withColumn(
        "foo",
        F.expr("transform(foo, x -> struct(coalesce(x.value, 10) as value, x.value2 as value2))")
    )
    

    现在,您可以显示 df1 中的值以验证它是否已更新:

    df1.select(F.expr("inline(foo)")).show()
    #+-----+------+
    #|value|value2|
    #+-----+------+
    #|   10|    30|
    #+-----+------+
    

    【讨论】:

    • 感谢@blackbishop。它接近我所需要的,但这意味着它丢失了 foo.xml 中的所有其他列。我需要保留这些并只编辑值列。
    • @doc 我更新了我的示例以展示如何保留结构的其他字段
    • 太棒了@blackbishop。我的实际模式在 foo 下大约有 20 列,所以我不得不写一个大表达式,但它工作得很好。谢谢
    猜你喜欢
    • 2022-11-10
    • 2021-11-23
    • 2021-05-05
    • 2020-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多