簡體   English   中英

根據地圖替換Spark Dataframe中的值

[英]Replace Values in Spark Dataframe based on Map

我有一個整數數據集,其中一些是真實數據,其中一些在一定閾值以上是錯誤代碼。 我也有一個列名映射到其錯誤代碼范圍的開頭。 我想使用此映射來有條件地替換值,例如,如果每列中的行的值都超出錯誤范圍的開始,則為None。

val errors = Map("Col_1" -> 100, "Col_2" -> 10)

val df = Seq(("john", 1, 100), ("jacob", 10, 100), ("heimer", 1000, 
1)).toDF("name", "Col_1", "Col_2")

df.take(3)
// name   | Col_1 | Col_2
// john   | 1     | 1
// jacob  | 10    | 10
// heimer | 1000  | 1

//create some function like this
def fixer = udf((column_value, column_name) => {
    val crit_val = errors(column_name)
    if(column_value >= crit_val) {
        None
    } else {
        column_value
    }
}

//apply it in some way
val fixed_df = df.columns.map(_ -> fixer(_))

//to get output like this:
fixed_df.take(3)
// name   | Col_1 | Col_2
// john   | 1     | 1
// jacob  | 10    | None
// heimer | None  | 1

使用UDF進行此操作不太方便-UDF需要一個特定的列(或多個列)並返回一個列,而在這里您要處理各種不同的列。 此外,在不需要UDF when ,可以使用Spark的內置方法執行檢查閾值並用某個常數替換值的操作。

因此,這是一種用於when對具有閾值的每個列進行使用的方法,從而迭代遍歷相關列並生成所需的DataFrame(我們將用null替換“壞”值):

import org.apache.spark.sql.functions._
import spark.implicits._

// fold the list of errors, replacing the original column
// with a "corrected" column with same name in each iteration
val newDf = errors.foldLeft(df) { case (tmpDF, (colName, threshold)) =>
  tmpDF.withColumn(colName, when($"$colName" > threshold, null).otherwise($"$colName"))
}

newDf.show()
// +------+-----+-----+
// |  name|Col_1|Col_2|
// +------+-----+-----+
// |  john|    1|    1|
// | jacob|   10| null|
// |heimer| null|    1|
// +------+-----+-----+

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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