使用可变架构创建 Pyspark 数据框
Creating a Pyspark data frame with variable schema
我想创建一个 pyspark 数据框,其中有一列具有可变模式。所以我的数据框看起来像这样:
| Id | Variable_Column |
|----|----------------------------------|
| 1 | [{"col1":"val1"}] |
| 2 | [{"col1":"val2", "col2":"val3"}] |
于是实现了这个。我是这样开始的:
schema = StructType([StructField("Id", IntegerType(), True),\
StructField("Variable_Column", ArrayType(StructType()), True)\
])
valdict = dict()
valdict["col1"] = "val1"
values = [(1, [valdict])]
df = spark.createDataFrame(values, schema)
display(df)
| Id | Variable_Column |
|----|-----------------|
| 1 | [{}] |
这样做我创建了一个空数组。这也感觉不对,我希望内部列的类型也被保留。请建议插入数据的正确方法是什么。
对于我的可变列,我使用“ArrayType(StructType())
”,这是要使用的正确列类型吗?
您可以按如下方式定义架构:
schema = StructType([StructField("Id", IntegerType(), True),\
StructField("Variable_Column", ArrayType(MapType(StringType(),StringType())), True)\
])
这将给出如下输出:
df.show()
+---+--------------------+
| Id| Variable_Column|
+---+--------------------+
| 1|[[col2 -> val3, c...|
+---+--------------------+
解决方案 1
如果您只想创建一个包含可变数量值的列,您可以使用 ArrayType
或 StructType
。在你的例子中,你定义了一个空的 StructType
,因此你得到了结果。
您可以这样定义数据框:
df1 = spark.createDataFrame([ (1, [('name1', 'val1'), ('name2', 'val2')]),
(2, [('name3', 'val3')])],
['Id', 'Variable_Column'])
df1.show(truncate=False)
与您提供的示例相对应:
+---+----------------------------+
|Id |Variable_Column |
+---+----------------------------+
|1 |[[name1,val1], [name2,val2]]|
|2 |[[name3,val3]] |
+---+----------------------------+
请注意,在这种情况下您不需要显式定义架构,但如果您愿意,它看起来像这样(您可以调用 df1.schema 顺便打印它):
schema = StructType([
StructField('Id',LongType()),
StructField('Variable_Column',ArrayType(StructType([
StructField('name',StringType()),
StructField('value',StringType())
])))
])
解决方案 2
非常相似,您可以像这样使用 MapType
类型:
df2 = spark.createDataFrame([ (1, dict([('name1', 'val1'), ('name2', 'val2')])),
(2, dict([('name3', 'val3')]) )
], ['Id', 'Variable_Column'])
df2.show(truncate=False)
+---+---------------------------------+
|Id |Variable_Column |
+---+---------------------------------+
|1 |Map(name2 -> val2, name1 -> val1)|
|2 |Map(name3 -> val3) |
+---+---------------------------------+
解决方案 3
在评论中,您说您还需要变量类型。数据帧不可能做到这一点。如果这确实是您想要的,那么您可能没有使用正确的工具。但如果这只是一个极端情况,您可以在这样的字符串中记录数据类型:
df3 = spark.createDataFrame([ (1, [('name1', 'val1', 'string'),
('name2', '0.6', 'double')]),
(2, [('name3', '3', 'integer')])],
['Id', 'Variable_Column'])
df3.show(truncate=False)
+---+-----------------------------------------+
|Id |Variable_Column |
+---+-----------------------------------------+
|1 |[[name1,val1,string], [name2,0.6,double]]|
|2 |[[name3,3,integer]] |
+---+-----------------------------------------+
我想创建一个 pyspark 数据框,其中有一列具有可变模式。所以我的数据框看起来像这样:
| Id | Variable_Column |
|----|----------------------------------|
| 1 | [{"col1":"val1"}] |
| 2 | [{"col1":"val2", "col2":"val3"}] |
于是实现了这个。我是这样开始的:
schema = StructType([StructField("Id", IntegerType(), True),\
StructField("Variable_Column", ArrayType(StructType()), True)\
])
valdict = dict()
valdict["col1"] = "val1"
values = [(1, [valdict])]
df = spark.createDataFrame(values, schema)
display(df)
| Id | Variable_Column |
|----|-----------------|
| 1 | [{}] |
这样做我创建了一个空数组。这也感觉不对,我希望内部列的类型也被保留。请建议插入数据的正确方法是什么。
对于我的可变列,我使用“ArrayType(StructType())
”,这是要使用的正确列类型吗?
您可以按如下方式定义架构:
schema = StructType([StructField("Id", IntegerType(), True),\
StructField("Variable_Column", ArrayType(MapType(StringType(),StringType())), True)\
])
这将给出如下输出:
df.show()
+---+--------------------+
| Id| Variable_Column|
+---+--------------------+
| 1|[[col2 -> val3, c...|
+---+--------------------+
解决方案 1
如果您只想创建一个包含可变数量值的列,您可以使用 ArrayType
或 StructType
。在你的例子中,你定义了一个空的 StructType
,因此你得到了结果。
您可以这样定义数据框:
df1 = spark.createDataFrame([ (1, [('name1', 'val1'), ('name2', 'val2')]),
(2, [('name3', 'val3')])],
['Id', 'Variable_Column'])
df1.show(truncate=False)
与您提供的示例相对应:
+---+----------------------------+
|Id |Variable_Column |
+---+----------------------------+
|1 |[[name1,val1], [name2,val2]]|
|2 |[[name3,val3]] |
+---+----------------------------+
请注意,在这种情况下您不需要显式定义架构,但如果您愿意,它看起来像这样(您可以调用 df1.schema 顺便打印它):
schema = StructType([
StructField('Id',LongType()),
StructField('Variable_Column',ArrayType(StructType([
StructField('name',StringType()),
StructField('value',StringType())
])))
])
解决方案 2
非常相似,您可以像这样使用 MapType
类型:
df2 = spark.createDataFrame([ (1, dict([('name1', 'val1'), ('name2', 'val2')])),
(2, dict([('name3', 'val3')]) )
], ['Id', 'Variable_Column'])
df2.show(truncate=False)
+---+---------------------------------+
|Id |Variable_Column |
+---+---------------------------------+
|1 |Map(name2 -> val2, name1 -> val1)|
|2 |Map(name3 -> val3) |
+---+---------------------------------+
解决方案 3
在评论中,您说您还需要变量类型。数据帧不可能做到这一点。如果这确实是您想要的,那么您可能没有使用正确的工具。但如果这只是一个极端情况,您可以在这样的字符串中记录数据类型:
df3 = spark.createDataFrame([ (1, [('name1', 'val1', 'string'),
('name2', '0.6', 'double')]),
(2, [('name3', '3', 'integer')])],
['Id', 'Variable_Column'])
df3.show(truncate=False)
+---+-----------------------------------------+
|Id |Variable_Column |
+---+-----------------------------------------+
|1 |[[name1,val1,string], [name2,0.6,double]]|
|2 |[[name3,3,integer]] |
+---+-----------------------------------------+