我创建了RDD[String]
,其中每个String
元素包含多个JSON
字符串,但所有这些JSON
字符串在整个RDD
上具有相同的方案。
例如:
名为RDD{String]
的 rdd
包含以下条目:
字符串1:
{"data":"abc", "field1":"def"}
{"data":"123", "field1":"degf"}
{"data":"87j", "field1":"hzc"}
{"data":"efs", "field1":"ssaf"}
字符串2:
{"data":"fsg", "field1":"agas"}
{"data":"sgs", "field1":"agg"}
{"data":"sdg", "field1":"agads"}
我的目标是将此RDD[String]
转换为DataFrame
。如果我这样做:
val df = rdd.toDF()
...,然后它无法正常工作。实际上df.count()
为我提供2
,而不是7
用于上述示例,因为JSON
字符串是批处理的,无法单独识别。
如何创建DataFrame
以便每行对应特定的JSON
字符串?
答案 0 :(得分:2)
我现在无法检查,但我认为这应该有效:
// split each string by newline character
val splitted: RDD[Array[String]] = rdd.map(_.split("\n"))
// flatten
val jsonRdd: RDD[String] = splitted.flatMap(identity)
答案 1 :(得分:1)
通过关注您在问题中提供的信息,以下内容可以作为您的解决方案:
import sqlContext.implicits._
val str1 = "{\"data\":\"abc\", \"field1\":\"def\"}\n{\"data\":\"123\", \"field1\":\"degf\"}\n{\"data\":\"87j\", \"field1\":\"hzc\"}\n{\"data\":\"efs\", \"field1\":\"ssaf\"}"
val str2 = "{\"data\":\"fsg\", \"field1\":\"agas\"}\n{\"data\":\"sgs\", \"field1\":\"agg\"}\n{\"data\":\"sdg\", \"field1\":\"agads\"}"
val input = Seq(str1, str2)
val rddData = sc.parallelize(input).flatMap(_.split("\n"))
.map(line => line.split(","))
.map(array => (array(0).split(":")(1).trim.replaceAll("\\W", ""), array(1).split(":")(1).trim.replaceAll("\\W", "")))
rddData.toDF("data", "field1").show
的被修改强>
您可以排除fieldNames并使用.toDF()
,但这会从您的数据中提供default column names
(例如_1
_2
或col_1
col_2
等)
相反,您可以创建schema
来创建dataframe
,如下所示(您可以添加更多字段)
val rddData = sc.parallelize(input).flatMap(_.split("\n"))
.map(line => line.split(","))
.map(array => Row.fromSeq(Seq(array(0).split(":")(1).trim.replaceAll("\\W", ""), array(1).split(":")(1).trim.replaceAll("\\W", ""))))
val schema = StructType(Array(StructField("data", StringType, true),
StructField("field1", StringType, true)))
sqlContext.createDataFrame(rddData, schema).show
或者
您可以直接创建dataset
,但需要case class
(您可以添加更多字段),如下所示
val dataSet = sc.parallelize(input).flatMap(_.split("\n"))
.map(line => line.split(","))
.map(array => Dinasaurius(array(0).split(":")(1).trim.replaceAll("\\W", ""),
array(1).split(":")(1).trim.replaceAll("\\W", ""))).toDS
dataSet.show
以上case class
的{{1}}是
dataset
我希望我回答你所有的问题