从两个不同的阵列中创建Dataframe会引发

时间:2017-02-24 22:25:37

标签: scala apache-spark

我正在使用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分隔记录。

与我在文件中创建数据帧所做的相比,在此方法中创建数据帧可能相当于什么。

1 个答案:

答案 0 :(得分:1)

我在你的问题中推断以下内容。

Array1只是一个条目col1^Acol2^Acol3

的rdd

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|
+------+------+------+