我有一個具有型別列的資料框MapType<StringType, StringType>。
|-- identity: map (nullable = true)
| |-- key: string
| |-- value: string (valueContainsNull = true)
身份列包含一個鍵“更新”。
-------------
identity |
------- -----
[update -> Y]|
[update -> Y]|
[update -> Y]|
[update -> Y]|
------- -----
如何將鍵“update”的值從“Y”更改為“N”?
我正在使用火花版本 2.3
任何幫助將不勝感激。謝謝!
uj5u.com熱心網友回復:
AFAIK,在 spark 2.3 中沒有內置函式來處理地圖。唯一的方法可能是設計一個UDF:
val df = Seq(Map(1 -> 2, 3 -> 4), Map(7 -> 8, 1 -> 6)).toDF("m")
// a function that sets the value "new" to all key equal to "1"
val fun = udf((m : Map[String, String]) =>
m.map{ case (key, value) => (key, if (key == "1") "new" else value) }
)
df.withColumn("m", fun('m)).show(false)
------------------
|m |
------------------
|{1 -> new, 3 -> 4}|
|{7 -> 8, 1 -> new}|
------------------
JSON解決方案
一種替代方法是分解地圖,進行更新并重新聚合。不幸的是,在 spark 2.3 中無法從動態數量的專案中創建地圖。但是,您可以將地圖聚合為 json 字典,然后使用該from_json函式。我很確定第一個解決方案會更有效,但誰知道呢。在 pyspark 中,這個解決方案可能比 UDF 更快。
df
.withColumn("id", monotonically_increasing_id)
.select($"id", explode('m))
.withColumn("value", when('key === "1" ,lit("new")).otherwise('value))
.withColumn("entry", concat(lit("\""), 'key, lit("\" : \""), 'value, lit("\"")))
.groupBy("id").agg( collect_list('entry) as "list")
.withColumn("json", concat(lit("{"), concat_ws(",", 'list), lit("}")))
.withColumn("m", from_json('json, MapType(StringType, StringType)))
.show(false)
這產生與以前相同的結果。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/468339.html
