是否可以在PySpark Dataframe中定义递归DataType



我想创建一个类似以下示例的模式:

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创建一个表

最新更新