[英]Scala/Spark : How to perform filter and change value of a column for a list of columns?
1)我有一個包含幾列的 DF,但最重要的是“col1”、“col2”……“col10”(10 列)。 我只對其中至少一列的值 > 1 的行感興趣。我現在擁有的是:
DF.filter(col(col1) > 1 or col(col2) > 1 or col(col3) > 1 or col(col4) > 1 or col(col5) > 1
or col(col6) > 1 or col(col7) > 1 or col(col8) > 1 or col(col9) > 1 or col(col10) > 1)
2) 與 #1 類似,我有另一個 DF,我需要將列列表的值減去 1
DF
.withColumn("col1", col("col1") - 1)
.withColumn("col2", col("col2") - 1)
.withColumn("col3", col("col3") - 1)
.withColumn("col4", col("col4") - 1)
// and so on .....
這些都可以工作,但是有沒有更優雅的方式來處理多列?
您可以創建一個感興趣的列的列表,並使用reduce
來組裝where
子句中的重復or
條件:
val df = Seq(
(101, 0, -1, -2, -3, -4),
(102, -1, 0, 1, 2, 3)
).toDF("id", "c1", "c2", "c3", "c4", "c5")
val colList = df.columns.filter(_.startsWith("c"))
df.where(colList.map(col(_) > 1).reduce(_ || _)).show
// +---+---+---+---+---+---+
// | id| c1| c2| c3| c4| c5|
// +---+---+---+---+---+---+
// |102| -1| 0| 1| 2| 3|
// +---+---+---+---+---+---+
對於重復的withColumn
轉換,請考慮使用foldLeft
:
colList.foldLeft(df)((acc, c) => acc.withColumn(c, col(c) - 1)).show
// +---+---+---+---+---+---+
// | id| c1| c2| c3| c4| c5|
// +---+---+---+---+---+---+
// |101| -1| -2| -3| -4| -5|
// |102| -2| -1| 0| 1| 2|
// +---+---+---+---+---+---+
但是,與使用重復的withColumn
,在一個轉換中作為ArrayType
列的元素跨列執行減法會更有效:
df.
withColumn("arr", array(colList.map(col(_) - 1): _*)).
select($"id" +: (0 until colList.size).map(i => $"arr"(i).as(colList(i))): _*)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.