如何将嵌套的结构列展开为多个列?

cbwuti44  于 2021-07-14  发布在  Spark
关注(0)|答案(2)|浏览(500)

我正在尝试用嵌套 struct 在多列中键入(见下文)。我正在使用的结构模式类似于 {"foo": 3, "bar": {"baz": 2}} .
理想情况下,我想把上面的内容扩展成两列( "foo" 以及 "bar.baz" ). 然而,当我尝试使用 .select("data.*") (其中 data 是结构列),我只得到列 foo 以及 bar ,在哪里 bar 仍然是一个 struct .
有没有一种方法可以扩展这两层的结构?

sdnqo3pr

sdnqo3pr1#

您可以选择 data.bar.baz 作为 bar.baz :

df.show()
+-------+
|   data|
+-------+
|[3,[2]]|
+-------+

df.printSchema()
root
 |-- data: struct (nullable = false)
 |    |-- foo: long (nullable = true)
 |    |-- bar: struct (nullable = false)
 |    |    |-- baz: long (nullable = true)

在Pypark中:

import pyspark.sql.functions as F
df.select(F.col("data.foo").alias("foo"), F.col("data.bar.baz").alias("bar.baz")).show()
+---+-------+
|foo|bar.baz|
+---+-------+
|  3|      2|
+---+-------+
dxxyhpgq

dxxyhpgq2#

最后,我使用了以下函数递归地“展开”分层结构:
基本上,它一直在挖掘 Struct 字段并保持其他字段不变,这种方法消除了需要很长时间 df.select(...)Struct 有很多领域。代码如下:


# Takes in a StructType schema object and return a column selector that flattens the Struct

def flatten_struct(schema, prefix=""):
    result = []
    for elem in schema:
        if isinstance(elem.dataType, StructType):
            result += flatten_struct(elem.dataType, prefix + elem.name + ".")
        else:
            result.append(col(prefix + elem.name).alias(prefix + elem.name))
    return result

df = sc.parallelize([Row(r=Row(a=1, b=Row(foo="b", bar="12")))]).toDF()
df.show()
+----------+
|         r|
+----------+
|[1,[12,b]]|
+----------+

df_expanded = df.select("r.*")
df_flattened = df_expanded.select(flatten_struct(df_expanded.schema))

df_flattened.show()
+---+-----+-----+
|  a|b.bar|b.foo|
+---+-----+-----+
|  1|   12|    b|
+---+-----+-----+

相关问题