我正在創建一個新的屬性x,并將屬性a b c串聯起來。如果x的總長度小于10,那么我想只給屬性c加上0的前綴。我怎樣才能做到這一點呢?
val x = when length(concat($"a"/span>, $"b", $"c")) < 10,
concat($"a", $"b", lpad($"c", 10, '0')
.否則(concat($"a"/span>, $"b"/span>, $"c"/span>)
上面的方法不會起作用,因為c列的前綴是0,直到長度為10,而我希望連接后的總長度為10。請建議。
uj5u.com熱心網友回復:
你可以使用一個sql運算式來處理lpad:
val df =Seq(("aaa"/span>, "bbb","cccc")。)
("a","b","c") 。
("a","b","1234567890123") 。
("a","b","") )。 toDF("a"/span>,"b"/span>,"c"/span>)
df. withColumn("x", when(length(concat($"a",$"b",$"c") < 10,
concat($"a", $"b", expr("lpad(c, 10 - char_length(a) - char_length(b), '0') "))
.否則(concat($"a",$"b",$"c"))
.顯示()
輸出:
--- --- ------------- ---------------
| a| b| c| x|
--- --- ------------- ---------------
|aaa|bbb|ccc| aaabbbcccc|
|A|B|C|Ab0000000C|
|A|B|1234567890123|AB1234567890123|
| ?????
--- --- ------------- ---------------
uj5u.com熱心網友回復:
從邏輯上講,你想要的是以下的內容:
val ab = concat($"a"/span>, $"b"/span>)
val x = concat(ab, lpad($"c", lit(10) - length(ab), lit("0") )
// ^ 不可能 ^ 不可能。
不幸的是這是不可能的,因為Spark Scala的 如果你檢查底層的Catalyst 下面是一個帶有一些邊緣情況的輸出示例:
標籤:lpad函式的簽名是str: Column, len: Int, pad: 而你不能提供Column物件作為len和pad引數。
StringLPad運算式型別,它不需要len和pad引數的常量。這意味著我們可以定義我們自己的lpad版本,它允許作為len和pad傳遞的Column值,這樣,每一行的長度和padding字串就可以是可變的。
import org.apache.spark.sql.Column。
import org.apache.spark.sql.function._
import org.apache.spark.sql.catalyst.expressions.StringLPad
def lpad_var(str: Column, len: Column, pad: Column) =
new Column(StringLPad(str.expr, len.expr, pad.expr)
val ab = concat($"a"/span>, $"b"/span>)
val x = concat(ab, lpad_var($"c", lit(10) - length(ab), lit("0" /span>)
val df = Seq(
("a"/span>, "bb"/span>, "c"/span>) 。
("aa"/span>, "bbb"/span>, "c"),
("", "", "")
).toDF("a"/span>, "b"/span>, "c"/span>)
df.select(x.as("x")).show()
// ---------- 。
// | x|。
// ----------
// |abb000000c|
// |aabbb0000c| // |aabbb0000c|
// |0000000000| // |0000000000|
// ----------
