[英]Reading JSON files into Spark Dataset and adding columns from a separate Map
Spark 2.1和Scala 2.11在这里。 我有一个大的Map[String,Date]
,里面有10K键/值对。 我还有10K JSON文件存在于Spark可访问的文件系统中:
mnt/
some/
path/
data00001.json
data00002.json
data00003.json
...
data10000.json
映射中的每个KV对对应于其各自的JSON文件(因此第一个映射KV对对应于data00001.json
等)
我想将所有这些JSON文件读入1个大型Spark Dataset
集中,当我在它时,向该数据集添加两个新列(JSON文件中不存在)。 每个映射键都是第一个新列的值,每个键的值将是第二个新列的值:
val objectSummaries = getScalaList()
val dataFiles = objectSummaries.filter { _.getKey.endsWith("data.json") }
val dataDirectories = dataFiles.map(dataFile => {
val keyComponents = dataFile.getKey.split("/")
val parent = if (keyComponents.length > 1) keyComponents(keyComponents.length - 2) else "/"
(parent, dataFile.getLastModified)
})
// TODO: How to take each KV pair from dataDirectories above and store them as the values for the
// two new columns?
val allDataDataset = spark.read.json("mnt/some/path/*.json")
.withColumn("new_col_1", dataDirectories._1)
.withColumn("new_col_2", dataDirectories._2)
我已经确认Spark将遵循通配符( mnt/some/path/*.json
allData.show()
并在删除withColumn
方法并执行allData.show()
时将所有JSON文件读入单个数据集。 所以我在那里都很好。
我正在努力的是: 如何添加两个新列,然后正确地拔出所有键/值映射元素?
如果我理解正确,您想要将地图中的KV与json文件中的数据帧相关联。
我将尝试将问题简化为仅3个文件和所有订购的3个键值。
val kvs = Map("a" -> 1, "b" -> 2, "c" -> 3)
val files = List("data0001.json", "data0002.json", "data0003.json")
定义一个案例类,用于处理更简单的文件,键,值
case class FileWithKV(fileName: String, key: String, value: Int)
将压缩文件和kvs
val filesWithKVs = files.zip(kvs)
.map(p => FileWithKV(p._1, p._2._1, p._2._2))
它看起来像这样
filesWithKVs: List[FileWithKV] = List(FileWithKV(data0001.json,a,1), FileWithKV(data0002.json,b,2), FileWithKV(data0003.json,c,3))
我们从一个初始数据框开始,从我们的集合的头部开始,然后将开始向左折叠以构建将保存所有文件的整个数据框,所有列都是从KV动态生成的
val head = filesWithKVs.head
val initialDf = spark
.read.json(head.filename)
.withColumn(s"new_col_1", lit(head.key))
.withColumn(s"new_col_2", lit(head.value))
现在是折叠部分
val dfAll = filesWithKVs.tail.foldLeft(initialDf)((df, fileWithKV) => {
val newDf = spark
.read.json(fileWithKV.filename)
.withColumn(s"new_col_1", lit(fileWithKV.key))
.withColumn(s"new_col_2", lit(fileWithKV.value))
// union the dataframes to capture file by file, key value with key value
df.union(newDf)
})
假设在json文件中,对于3个json文件中的每一个,json文件都是名为bar的列和值foo,数据框将如下所示
+---+----------+----------+
|bar|new_col_1 |new_col_2 |
+---+----------+----------+
|foo| a| 1|
|foo| b| 2|
|foo| c| 3|
+---+----------+----------+
我认为你应该为此创建自己的数据源。 这个新的数据源将了解您的特定文件夹结构和内容结构。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.