如何将嵌套的Struct列展开为多列?

时间:2017-10-24 14:31:10

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

我正在尝试将嵌套struct类型(见下文)的DataFrame列扩展为多个列。我正在使用的Struct模式看起来像{"foo": 3, "bar": {"baz": 2}}

理想情况下,我想将上述内容扩展为两列("foo""bar.baz")。但是,当我尝试使用.select("data.*")(其中data是结构列)时,我只会获得列foobar,其中bar仍然是{ {1}}。

有没有办法可以扩展两个图层的结构?

2 个答案:

答案 0 :(得分:7)

您可以选择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| +---+-------+ 作为<p>

line-height

在pyspark:

span, p {
   line-height: 2em;
   font-size: 14px;
}

答案 1 :(得分:2)

我最终选择了以下函数,以递归方式“展开”分层Struct的结构:

基本上,它不断挖掘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|
+---+-----+-----+