2024-04-25 20:42:00 发布
网友
我试图将嵌套struct类型的DataFrame列(见下文)扩展到多个列。我正在使用的结构模式类似于{"foo": 3, "bar": {"baz": 2}}。
struct
{"foo": 3, "bar": {"baz": 2}}
理想情况下,我希望将以上内容扩展为两列("foo"和"bar.baz")。但是,当我尝试使用.select("data.*")(其中data是结构列)时,我只得到foo和bar,其中bar仍然是struct。
"foo"
"bar.baz"
.select("data.*")
data
foo
bar
有没有方法可以扩展这两层的结构?
您可以选择data.bar.baz作为bar.baz:
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)
在pyspark中:
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| +---+-------+
最后,我使用了以下递归“展开”分层结构的函数:
本质上,它一直在挖掘Struct字段,并保持其他字段不变,这种方法消除了当Struct有很多字段时需要有非常长的df.select(...)语句的情况。代码如下:
Struct
df.select(...)
# 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| +---+-----+-----+
您可以选择
data.bar.baz
作为bar.baz
:在pyspark中:
最后,我使用了以下递归“展开”分层结构的函数:
本质上,它一直在挖掘
Struct
字段,并保持其他字段不变,这种方法消除了当Struct
有很多字段时需要有非常长的df.select(...)
语句的情况。代码如下:相关问题 更多 >
编程相关推荐