我想创建一个类似以下示例的模式:
friendSchema = StructType([
StructField("firstname",StringType(),True),
StructField("middlename",StringType(),True),
StructField("friends",**friendSchema**,True)
我知道数据必须规范化,但我想知道Spark是否具有创建如上所述模式的功能。如果是这样,怎么能做到呢?使用UDT是否可行?
是的,这是可能的。您要做的是称为嵌套结构。StructType
模式本身可以包含StructType
字段,这些字段将执行您想要的操作。例如:
def test_build_nested_schema(self):
internal_struct = StructType([(StructField("friend_struct", StringType()))])
friend_schema = StructType([
StructField("firstname", StringType(), True),
StructField("middlename", StringType(), True),
StructField("friends", internal_struct, True)])
empty_df = self.spark.createDataFrame([], schema=friend_schema)
empty_df.printSchema()
将输出:
root
|-- firstname: string (nullable = true)
|-- middlename: string (nullable = true)
|-- friends: struct (nullable = true)
| |-- friend_struct: string (nullable = true)
文档链接。
我认为也许您应该退一步,重新思考您的解决方案。
你正在尝试为朋友之间的关系建模,最好的方法可能是使用Graphs。
请尝试阅读以下内容:https://databricks.com/blog/2016/03/03/introducing-graphframes.html
你想要的是不可能的。您要做的是一个具有无限子模式的模式。
它可以通过递归函数完成:
from pyspark.sql.types import *
def friendSchema(n):
if n == 0:
return StructType([
StructField("firstname", StringType(), True),
StructField("middlename", StringType(), True)])
else:
return StructType([
StructField("firstname", StringType(), True),
StructField("middlename", StringType(), True),
StructField("friends", friendSchema(n - 1))])
这是不可能的,
但是您可以通过另一种方法来实现它。通过将数据存储为JSON。并将其作为虚拟表读取。我知道这将花费I/o量但是在这个步骤之后,您将从虚拟表的选择中创建一个表。
- 将数据转换为JSON(使用递归(
- 把它放在一张临时桌子上
- 从临时表上的select创建一个表