Apache spark 从嵌套结构中提取Spark数据帧
我有一个嵌套结构的数据帧(最初是mapreduce作业的Avro输出)。我想把它弄平。原始DataFrame的架构如下所示(简化): 在Json表示中,一行数据如下所示:Apache spark 从嵌套结构中提取Spark数据帧,apache-spark,dataframe,apache-spark-sql,spark-dataframe,avro,Apache Spark,Dataframe,Apache Spark Sql,Spark Dataframe,Avro,我有一个嵌套结构的数据帧(最初是mapreduce作业的Avro输出)。我想把它弄平。原始DataFrame的架构如下所示(简化): 在Json表示中,一行数据如下所示: {"key": {"outcome": false, "date": "2015-01-01", "age" : 20, "features": { {"f1": 10.0, "f2": 11.0, ... "f100
{"key":
{"outcome": false,
"date": "2015-01-01",
"age" : 20,
"features": {
{"f1": 10.0,
"f2": 11.0,
...
"f100": 20.1
}
},
"value": null
}
df.select("key.*").show
+----+------------+-------+
|date| features |outcome|
+----+------------+-------+
|2015| [v1,v2,...]| false|
+----+------------+-------+
...
(truncated)
df.select("key.*").printSchema
root
|-- date: string (nullable = true)
|-- features: struct (nullable = true)
| |-- f1: string (nullable = true)
| |-- f2: string (nullable = true)
| |-- ...
|-- outcome: boolean (nullable = true)
df.select("key.features.*").show
+---+---+---
| f1| f2|...
+---+---+---
| v1| v2|...
+---+---+---
...
(truncated)
df.select("key.features.*").printSchema
root
|-- f1: string (nullable = true)
|-- f2: string (nullable = true)
|-- ...
功能图所有行的结构都相同,即键集相同(f1、f2、…、f100)。我所说的“展平”是指以下内容
+----------+----------+---+----+----+-...-+------+
| outcome| date|age| f1| f2| ... | f100|
+----------+----------+---+----+----+-...-+------+
| true|2015-01-01| 20|10.0|11.0| ... | 20.1|
...
(truncated)
我正在使用Spark 2.1.0的Spark avro软件包
原始数据帧由
import com.databricks.spark.avro._
val df = spark.read.avro("path/to/my/file.avro")
// it's nested
df.show()
+--------------------+------+
| key| value|
+--------------------+------+
|[false,2015... |[null]|
|[false,2015... |[null]|
...
(truncated)
非常感谢您的帮助 在Spark中,您可以从嵌套的AVRO文件中提取数据。例如,您提供的JSON:
{"key":
{"outcome": false,
"date": "2015",
"features": {
{"f1": v1,
"f2": v2,
...
}
},
"value": null
}
从AVRO处读取后:
import com.databricks.spark.avro._
val df = spark.read.avro("path/to/my/file.avro")
可以提供来自嵌套JSON的扁平化数据。为此,您可以编写如下代码:
{"key":
{"outcome": false,
"date": "2015-01-01",
"age" : 20,
"features": {
{"f1": 10.0,
"f2": 11.0,
...
"f100": 20.1
}
},
"value": null
}
df.select("key.*").show
+----+------------+-------+
|date| features |outcome|
+----+------------+-------+
|2015| [v1,v2,...]| false|
+----+------------+-------+
...
(truncated)
df.select("key.*").printSchema
root
|-- date: string (nullable = true)
|-- features: struct (nullable = true)
| |-- f1: string (nullable = true)
| |-- f2: string (nullable = true)
| |-- ...
|-- outcome: boolean (nullable = true)
df.select("key.features.*").show
+---+---+---
| f1| f2|...
+---+---+---
| v1| v2|...
+---+---+---
...
(truncated)
df.select("key.features.*").printSchema
root
|-- f1: string (nullable = true)
|-- f2: string (nullable = true)
|-- ...
或者像这样:
{"key":
{"outcome": false,
"date": "2015-01-01",
"age" : 20,
"features": {
{"f1": 10.0,
"f2": 11.0,
...
"f100": 20.1
}
},
"value": null
}
df.select("key.*").show
+----+------------+-------+
|date| features |outcome|
+----+------------+-------+
|2015| [v1,v2,...]| false|
+----+------------+-------+
...
(truncated)
df.select("key.*").printSchema
root
|-- date: string (nullable = true)
|-- features: struct (nullable = true)
| |-- f1: string (nullable = true)
| |-- f2: string (nullable = true)
| |-- ...
|-- outcome: boolean (nullable = true)
df.select("key.features.*").show
+---+---+---
| f1| f2|...
+---+---+---
| v1| v2|...
+---+---+---
...
(truncated)
df.select("key.features.*").printSchema
root
|-- f1: string (nullable = true)
|-- f2: string (nullable = true)
|-- ...
如果这是您期望的输出。谢谢@himanshullTian!我不知道您可以使用
*
作为选择(“键。*”)
。这让事情更接近我的需要。但是df.select(“key.features.*)
不起作用,因为features
是一个map
而不是struct
,我得到了org.apache.spark.sql.AnalysisException:只能星型扩展struct数据类型
。你能给我个建议吗?我还编辑了我的问题,以便更清楚地说明我所说的扁平化结构是什么意思。@random我试图扁平化Spark数据帧中的map
类型,但没有成功:(我认为*
模式对map
类型不起作用。感谢@himanshullTian对此进行研究。一些人建议使用“爆炸”DataFrame的方法,但我不认为它直接适用于我的情况。似乎另一种选择是将原始数据帧视为行的RDD,并使用新模式手动将每行映射到所需的格式,然后转换回df。我希望这样做更优雅。。你是对的@Random确定性!explode
不会起作用k用于此用例。也许将它映射到每一行到不同的格式可能会像预期的那样工作。我花了几个小时试图找出如何分解avro嵌套元素。直到找到您的答案。您是否建议提供进一步的文档。