我與結構的蜂巢表:如何從字符串中創建數據框鍵=由「;」分隔的值
我需要閱讀的字符串場,打破了鍵,變成一個蜂箱表列,最終的表應該是這樣的:
非常重要的,關鍵的字符串中的數字是動態的,按鍵的名稱也是動態的
嘗試使用spark SQL讀取字符串,根據所有字符串創建一個schema架構並使用saveAsTable()函數轉換數據幀配置表,但不知道如何執行此操作
有什麼建議嗎?
我與結構的蜂巢表:如何從字符串中創建數據框鍵=由「;」分隔的值
我需要閱讀的字符串場,打破了鍵,變成一個蜂箱表列,最終的表應該是這樣的:
非常重要的,關鍵的字符串中的數字是動態的,按鍵的名稱也是動態的
嘗試使用spark SQL讀取字符串,根據所有字符串創建一個schema架構並使用saveAsTable()函數轉換數據幀配置表,但不知道如何執行此操作
有什麼建議嗎?
一個天真的(假設獨特(code, date)
組合和沒有嵌入string
=
和;
)可以是這樣的:
import org.apache.spark.sql.functions.{explode, split}
val df = Seq(
(1, 1, "key1=value11;key2=value12;key3=value13;key4=value14"),
(1, 2, "key1=value21;key2=value22;key3=value23;key4=value24"),
(2, 4, "key3=value33;key4=value34;key5=value35")
).toDF("code", "date", "string")
val bits = split($"string", ";")
val kv = split($"pair", "=")
df
.withColumn("bits", bits) // Split column by `;`
.withColumn("pair", explode($"bits")) // Explode into multiple rows
.withColumn("key", kv(0)) // Extract key
.withColumn("val", kv(1)) // Extract value
// Pivot to wide format
.groupBy("code", "date")
.pivot("key")
.agg(first("val"))
// +----+----+-------+-------+-------+-------+-------+
// |code|date| key1| key2| key3| key4| key5|
// +----+----+-------+-------+-------+-------+-------+
// | 1| 2|value21|value22|value23|value24| null|
// | 1| 1|value11|value12|value13|value14| null|
// | 2| 4| null| null|value33|value34|value35|
// +----+----+-------+-------+-------+-------+-------+
這可以很容易地調整處理的情況下(code, date)
不是唯一的,你可以使用UDF
處理更復雜的string
模式。
根據您使用的語言和列數,您可能更適合使用RDD
或Dataset
。還有一個值得考慮的是放棄全部的explode
/pivot
以支持UDF。
val parse = udf((text: String) => text.split(";").map(_.split("=")).collect {
case Array(k, v) => (k, v)
}.toMap)
val keys = udf((pairs: Map[String, String]) => pairs.keys.toList)
// Parse strings to Map[String, String]
val withKVs = df.withColumn("kvs", parse($"string"))
val keys = withKVs
.select(explode(keys($"kvs"))).distinct // Get unique keys
.as[String]
.collect.sorted.toList // Collect and sort
// Build a list of expressions for subsequent select
val exprs = keys.map(key => $"kvs".getItem(key).alias(key))
withKVs.select($"code" :: $"date" :: exprs: _*)
在星火1.5,你可以嘗試:
val keys = withKVs.select($"kvs").rdd
.flatMap(_.getAs[Map[String, String]]("kvs").keys)
.distinct
.collect.sorted.toList
不幸的是我使用的是spark 1.5,並且pivot函數不可用,否則不會使用它? –
用RDD替換'Dataset'後的第二種方法應該很好。 – zero323
.select不適用於RDD,我必須更改? –
有多遠你就分裂了分號鍵和值得到? –
目前使用蜂巢式查詢,但速度很慢。 –