我有一个类似
的JSON{ 1234 : "blah1", 9807: "blah2", 467: "blah_k", ...}
已写入压缩文件。它是一个ID空间到另一个ID空间的映射,其中键是int
,值是string
。
我想在Spark中将其加载为DataFrame
。
我将其加载为
val df = spark.read.format("json").load("my_id_file.json.gz")
默认情况下,Spark为其加载了一个类似如下的模式
|-- 1234: string (nullable = true)
|-- 9807: string (nullable = true)
|-- 467: string (nullable = true)
相反,我希望我的DataFrame
看起来像
+----+------+
|id1 |id2 |
+----+------+
|1234|blah1 |
|9007|blah2 |
|467 |blah_k|
+----+------+
所以,我尝试了以下方法。
import org.apache.spark.sql.types._
val idMapSchema = StructType(Array(StructField("id1", IntegerType, true), StructField("id2", StringType, true)))
val df = spark.read.format("json").schema(idMapSchema).load("my_id_file.json.gz")
但是,加载的数据帧看起来像
scala> df.show
+----+----+
|id1 |id2 |
+----+----+
|null|null|
+----+----+
如何指定解决方案?是否有“纯”数据框方法(无需创建RDD然后创建数据框)?
答案 0 :(得分:0)
一种实现此目的的方法是将输入文件读取为textFile
,并在map()
中应用解析逻辑,然后将结果转换为数据帧
import scala.collection.JavaConversions._
import scala.collection.mutable.ListBuffer
val rdd = sparkSession.sparkContext.textFile("my_input_file_path")
.map(row => {
val list = new ListBuffer[String]()
val inputJson = new JSONObject(row)
for (key <- inputJson.keySet()) {
val resultJson = new JSONObject()
resultJson.put("col1", key)
resultJson.put("col2", inputJson.get(key))
list += resultJson.toString()
}
list
}).flatMap(row => row)
val df = sparkSession.read.json(rdd)
df.printSchema()
df.show(false)
输出:
root
|-- col1: string (nullable = true)
|-- col2: string (nullable = true)
+----+------+
|col1|col2 |
+----+------+
|1234|blah1 |
|467 |blah_k|
|9807|blah2 |
+----+------+