簡體   English   中英

Scala/Spark:如何為列列表執行過濾器和更改列值?

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM