我正在使用spark streaming并从kafka消息创建此数据框:
|customer|initialLoadComplete|initialLoadRunning| messageContent| tableName|
+--------+-------------------+------------------+--------------------+-----------------+
| A| false| true|TEFault_IdReason...|Timed_Event_Fault|
| A| false| true|TEFault_IdReason...|Timed_Event_Fault|
+--------+-------------------+------------------+--------------------+-----------------+
现在我要提取出messageContent,messageContent基本上就像一个包含原始数据的CSV,第一行是列。 我可以从messageContent字段中以下列方式提取标题。
val Array1 = ssc.sparkContext.parallelize(rowD.getString(2).split("\u0002")(0))
所以Array1看起来像这样:
Array1: col1^Acol2^Acol3
Array2基本上是原始数据,每列值由^ A分隔,记录由^ B分隔。
^ A是列分隔符。 ^ B是记录分隔符
所以这就是array2的样子:
Array2 = value1^Avalue2^Avalue3^Bvalue4^Avalue5^Avalue6^Bvalue7^Avalue8^Avalue9
基本上我想创建一个数据帧,所以看起来像这样:
col1 | col2 | col3
-------------------------
value1 | value2 | value3
value4 | value5 | value6
value7 | value8 | value9
^ B是记录分隔符。
当我们从hdfs文件中读取数据时,我们通过以下命令创建了一个数据帧:
val df = csc.read.format("com.databricks.spark.csv").option("header", "true").option("inferSchema", "true").option("delimiter", "\u0001").load(hdfsFile)
但是这次我从内存中的两个数组创建一个数据帧。 Array1是array2中值的标头,array2由^ B分隔记录。
与我在文件中创建数据帧所做的相比,在此方法中创建数据帧可能相当于什么。
答案 0 :(得分:1)
我在你的问题中推断以下内容。
Array1只是一个条目col1^Acol2^Acol3
Array2是一个rdd,每个条目看起来像这样。 value1^Avalue2^Avalue3^Bvalue4^Avalue5^Avalue6^Bvalue7^Avalue8^Avalue9
有了这些假设,以下内容应该有效。
val array1 = sc.parallelize(Seq("col1\u0002col2\u0002col3"))
val array2 = sc.parallelize(Seq("value1\u0001value2\u0001value3\u0002value4\u0001value5\u0001value6\u0002value7\u0001value8\u0001value9"))
val data = array2.flatMap(x => x.split("\u0002")).map(x => x.split('\u0001')).collect()
val result = array2
.flatMap(x => x.split("\u0002"))
.map(x => x.split('\u0001'))
.map({ case Array(x,y,z) => (x,y,z)})
.toDF(array1.flatMap(x => x.split('\u0002')).collect(): _*)
result.show()
+------+------+------+
| col1| col2| col3|
+------+------+------+
|value1|value2|value3|
|value4|value5|value6|
|value7|value8|value9|
+------+------+------+