[英]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.