Python 使用变量模式创建Pyspark数据帧

Python 使用变量模式创建Pyspark数据帧,python,apache-spark,pyspark,apache-spark-sql,pyspark-dataframes,Python,Apache Spark,Pyspark,Apache Spark Sql,Pyspark Dataframes,我想创建一个pyspark数据框架,其中有一个具有可变模式的列。因此,我的数据框可以如下所示: | Id | Variable_Column | |----|----------------------------------| | 1 | [{"col1":"val1"}] | | 2 | [{"col1":"val2", "col2&q

我想创建一个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  | [{}]            |
所以要做到这一点。我是这样开始的:

| 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

如果只想创建一个具有可变数量值的列,可以使用
StructType
ArrayType
。在本例中,您定义了一个空的
StructType
,因此得到了结果

您可以这样定义数据帧:

| 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  | [{}]            |
df1=spark.createDataFrame([(1,[('name1','val1'),('name2','val2')]),
(2,[('name3','val3'))],
['Id','Variable_Column'])
df1.show(truncate=False)
这与您提供的示例相对应:

+---+----------------------------+
|Id |变量_列|
+---+----------------------------+
|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
类型:

| 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  | [{}]            |
df2=spark.createDataFrame([(1,dict([('name1','val1'),('name2','val2')]),
(2,dict([('name3','val3')]))
],['Id','Variable_Column'])
df2.show(truncate=False)
+---+---------------------------------+
|Id |变量_列|
+---+---------------------------------+
|1 |地图(名称2->val2,名称1->val1)|
|2 |地图(名称3->val3)|
+---+---------------------------------+
解决方案3

在注释中,您说您还需要变量类型。这在数据帧中是不可能的。如果这是您真正想要的,那么您可能没有使用正确的工具。但若这只是一个小案例,您可以将数据类型的记录保存在如下字符串中:

| 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  | [{}]            |
df3=spark.createDataFrame([(1,[('name1','val1','string'),
('name2','0.6','double')),
(2,[('name3','3','integer')]],
['Id','Variable_Column'])
df3.show(truncate=False)
+---+-----------------------------------------+
|Id |变量_列|
+---+-----------------------------------------+
|1 |[[name1,val1,string],[name2,0.6,double]]|
|2 |[[name3,3,integer]]|
+---+-----------------------------------------+

您能否提供一个详细的模式示例,并准确地告诉我们您对该变量列的期望值?我的主要问题是:什么是变量?长度?类型?结构?嗨。在我的用例中,它可以是上面的任何一个。例如,第一行可以有两个整型键值对。第二行可以有2个字符串类型2个整数类型等。在pyspark数据帧中,这样的情况可能吗?如果不是的话,什么是处理问题的正确方法?这在标准spark中是不可能的。列具有
数据类型
,该列中的所有值都必须具有此类型。可变长度可以通过数组或映射实现。但据我所知,你只能这么做。有变通办法,但在普通Pypark中没有。让我试着提供一个解决方案。谢谢你的解决方案,这很有帮助。我采纳了解决方案3的想法,做了一些更改,并将模式存储在单独的模式文件中。虽然我希望data frame在默认情况下具有该功能。