我在 spark 資料框中有資料,我需要按名稱搜索元素,將值附加到串列中,并將搜索到的元素拆分為資料框的單獨列。
我正在使用 scala,下面是我當前代碼的示例,該代碼可用于獲取第一個值,但我需要附加所有可用值,而不僅僅是第一個值。
我是 Scala(和 python)的新手,所以任何幫助將不勝感激!
val getNumber: (String => String) = (colString: String) => {
if (colString != null) {
raw"number:(\d )".r
.findAllIn(colString)
.group(1)
}
else
null
}
val udfGetColumn = udf(getNumber)
val mydf = df.select(cols.....)
.withColumn("var_number", udfGetColumn($"var"))
示例資料:
------ ----------------------------------------------------------------------------------------------------------------------------------------------------------------
| key| var |
------ ----------------------------------------------------------------------------------------------------------------------------------------------------------------
|1 |["[number:123456 rate:111970 position:1]","[number:123457 rate:662352 position:2]","[number:123458 rate:890 position:3]","[number:123459 rate:190 position:4]"] | |
|2 |["[number:654321 rate:211971 position:1]","[number:654322 rate:124 position:2]","[number:654323 rate:421 position:3]"] |
------ ----------------------------------------------------------------------------------------------------------------------------------------------------------------
預期結果:
------ ------------------------------------------------------------
| key| var_number | var_rate | var_position |
------ ------------------------------------------------------------
|1 | 123456 | 111970 | 1 |
|1 | 123457 | 662352 | 2 |
|1 | 123458 | 890 | 3 |
|1 | 123459 | 190 | 4 |
|2 | 654321 | 211971 | 1 |
|2 | 654322 | 124 | 2 |
|2 | 654323 | 421 | 3 |
------ ----------------- --------------------- --------------------
uj5u.com熱心網友回復:
您不需要在此處使用 UDF。在使用函式洗掉方括號 ( )后,您可以通過將每個元素轉換為映射來輕松地創建transform陣列列。最后,分解轉換后的陣列并選擇欄位:varstr_to_map[]regexp_replace
val df = Seq(
(1, Seq("[number:123456 rate:111970 position:1]", "[number:123457 rate:662352 position:2]", "[number:123458 rate:890 position:3]", "[number:123459 rate:190 position:4]")),
(2, Seq("[number:654321 rate:211971 position:1]", "[number:654322 rate:124 position:2]", "[number:654323 rate:421 position:3]"))
).toDF("key", "var")
val result = df.withColumn(
"var",
explode(expr(raw"transform(var, x -> str_to_map(regexp_replace(x, '[\\[\\]]', ''), ' '))"))
).select(
col("key"),
col("var").getField("number").alias("var_number"),
col("var").getField("rate").alias("var_rate"),
col("var").getField("position").alias("var_position")
)
result.show
// --- ---------- -------- ------------
//|key|var_number|var_rate|var_position|
// --- ---------- -------- ------------
//| 1| 123456| 111970| 1|
//| 1| 123457| 662352| 2|
//| 1| 123458| 890| 3|
//| 1| 123459| 190| 4|
//| 2| 654321| 211971| 1|
//| 2| 654322| 124| 2|
//| 2| 654323| 421| 3|
// --- ---------- -------- ------------
從您的評論看來,該列var的型別是字串而不是陣列。在這種情況下,您可以首先通過洗掉[]和"字符來轉換它,然后用逗號分割以獲得一個陣列:
val df = Seq(
(1, """["[number:123456 rate:111970 position:1]", "[number:123457 rate:662352 position:2]", "[number:123458 rate:890 position:3]", "[number:123459 rate:190 position:4]"]"""),
(2, """["[number:654321 rate:211971 position:1]", "[number:654322 rate:124 position:2]", "[number:654323 rate:421 position:3]"]""")
).toDF("key", "var")
val result = df.withColumn(
"var",
split(regexp_replace(col("var"), "[\\[\\]\"]", ""), ",")
).withColumn(
"var",
explode(expr("transform(var, x -> str_to_map(x, ' '))"))
).select(
// select your columns as above...
)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/394711.html
標籤:斯卡拉 阿帕奇火花 apache-spark-sql 火花流
