Dataframe 从pyspark中的列表列表中提取列

Dataframe 从pyspark中的列表列表中提取列,dataframe,apache-spark,pyspark,apache-spark-sql,Dataframe,Apache Spark,Pyspark,Apache Spark Sql,我一直在尝试从列表中提取列,但无法想象如何做。我对spark是个新手。在Spark 2.4.3上运行pyspark 我的json组织如下: { "meta" : { ... }, "data" : [[ "a", 0, null, "{ }"], [ "b", 0, null, "{ }"], [ "c", 0, null, "

我一直在尝试从列表中提取列,但无法想象如何做。我对spark是个新手。在Spark 2.4.3上运行pyspark

我的json组织如下:

{ "meta" : { ... },
  "data" : 
  [[ "a", 0, null, "{ }"],
   [ "b", 0, null, "{ }"],
   [ "c", 0, null, "{ }"],
   ] }
我想把“数据”部分分成几列,比如

 +------+------+------+------+
 | col1 | col2 | col3 | col4 |
 +------+------+------+------+
 |   a  |   0  | None | "{ }"|
 |   b  |   0  | None | "{ }"|
 |   c  |   0  | None | "{ }"|
我读取了数据帧,printSchema()显示了这一点

root
 |-- data: array (nullable = true)
 |    |-- element: array (containsNull = true)
 |    |    |-- element: string (containsNull = true)
 |-- meta: struct (nullable = true)
 |    |-- view: struct (nullable = true)
 |    |    |-- approvals: array (nullable = true) ...
我的大致形状是70列650k行


我能够分解df以仅获取
数据部分,但我被卡住了。

首先分解行,然后使用Python中的
[]
选择数组元素

df2 = df.select(F.explode('data').alias('data')) \
        .select(*[F.col('data')[i].alias('col%s'%(i+1)) for i in range(4)])

df2.show()
+----+----+----+----+
|col1|col2|col3|col4|
+----+----+----+----+
|   a|   0|null| { }|
|   b|   0|null| { }|
|   c|   0|null| { }|
+----+----+----+----+

为什么不使用SparkSession.createDataFrame()方法呢

您可以为此方法提供数据和模式参数,并获取spark dataframe

例如:

from pyspark.sql import SparkSession

sparkSession = SparkSession.builder.getOrCreate()
df = sparkSession.createDataFrame(data)
如果spark无法从数据推断模式,则还需要提供模式

from pyspark.sql.types import StructType

struct = StructType()
struct.add("col1", "string", True)
struct.add("col2", "integer", True)
struct.add("col3", "string", True)
struct.add("col4", "string", True)


df = sparkSession.createDataFrame(data=data, schema=struct)
此外,您可以使用pyspark类型类而不是python基元类型名。

模块包含简单类型(StringType、IntegerType等)和复杂类型(ArrayType、MapType等)


最后注意:数据不能包含
null
,在python中应该是
None
。spark DataFrame.show()将
None
列打印为
null

您可以通过
getItem
函数访问数组的各个元素,如下所示。我不想指定模式,因为我有70列。