0

일부 열을 가릴 필요가있는 테이블이 있습니다. 마스크 할 열은 테이블마다 다르며이 열은 application.conf 파일에서 읽습니다. 우리는 내가 순서대로 이러한 열을 얻을 후 이름과 나이 열을 마스크하려면Spark 2를 사용하여 열을 마스크하는 방법은 무엇입니까?

는 예를 들어, 직원 테이블

+----+------+-----+---------+ 
| id | name | age | address | 
+----+------+-----+---------+ 
| 1 | abcd | 21 | India | 
+----+------+-----+---------+ 
| 2 | qazx | 42 | Germany | 
+----+------+-----+---------+ 

아래와 같이. 마스킹 후

val mask = Seq("name", "age") 

예상 값은 다음과 같습니다

+----+----------------+----------------+---------+ 
| id | name   | age   | address | 
+----+----------------+----------------+---------+ 
| 1 | *** Masked *** | *** Masked *** | India | 
+----+----------------+----------------+---------+ 
| 2 | *** Masked *** | *** Masked *** | Germany | 
+----+----------------+----------------+---------+ 

나는 직원 테이블에게 데이터 프레임을 가지고 있다면, 이러한 열을 마스크 할 수있는 방법은 무엇입니까?

나는 다음과 같이 payment 테이블이 다음 내가이 mask.foreach(c => base.withColumn(c, regexp_replace(col(c), "^.*?$", "*** Masked ***")))처럼 뭔가를 시도했지만 아무것도 반환하지 않았다

+----+------+--------+----------+ 
| id | name | salary | tax_code | 
+----+------+--------+----------+ 
| 1 | abcd | 12345 | KT10  | 
+----+------+--------+----------+ 
| 2 | qazx | 98765 | AD12d | 
+----+------+--------+----------+ 

val mask = Seq("name", "salary") 

으로 순서에 마스크 열을 얻을 namesalary 열을 마스크합니다.


@philantrovert 덕분에 해결책을 발견했습니다. 다음은 내가 사용한 해결책입니다.

def maskData(base: DataFrame, maskColumns: Seq[String]) = { 
    val maskExpr = base.columns.map { col => if(maskColumns.contains(col)) s"'*** Masked ***' as ${col}" else col } 
    base.selectExpr(maskExpr: _*) 
} 

답변

1

귀하의 문

mask.foreach(c => base.withColumn(c, regexp_replace(col(c), "^.*?$", "*** Masked ***"))) 

너무 좋은 소리를하지 않는 List[org.apache.spark.sql.DataFrame]를 반환합니다.

당신은 selectExpr를 사용하고 사용하여 regexp_replace 표현을 생성 할 수 있습니다

base.show 
+---+----+-----+-------+ 
| id|name| age|address| 
+---+----+-----+-------+ 
| 1|abcd|12345| KT10 | 
| 2|qazx|98765| AD12d| 
+---+----+-----+-------+ 

val mask = Seq("name", "age") 
val expr = df.columns.map { col => 
    if (mask.contains(col)) s"""regexp_replace(${col}, "^.*", "** Masked **") as ${col}""" 
    else col 
} 

이 지금 mask

Array[String] = Array(id, regexp_replace(name, "^.*", "** Masked **") as name, regexp_replace(age, "^.*", "** Masked **") as age, address) 

사용할 수있는 시퀀스에 존재하는 열에 대한 regex_replace와 표현을 생성합니다 생성 된 시퀀스상의 selectExpr

base.selectExpr(expr: _*).show 

+---+------------+------------+-------+ 
| id|  name|   age|address| 
+---+------------+------------+-------+ 
| 1|** Masked **|** Masked **| KT10 | 
| 2|** Masked **|** Masked **| AD12d| 
+---+------------+------------+-------+ 
+0

감사합니다. 효과가있다. – Shekhar

1

아래 코드를 확인하십시오. 열쇠는 udf 기능입니다.

val df = ss.sparkContext.parallelize(Seq (
    ("c1", "JAN-2017", 49), 
    ("c1", "MAR-2017", 83), 
)).toDF("city", "month", "sales") 
df.show() 

val mask = udf((s : String) => { 
    "*** Masked ***" 
}) 

df.withColumn("city", mask($"city")).show` 
3

가장 간단하고 빠른 방법은 withColumn을 사용하고 열의 값을 "*** Masked ***"으로 덮어 쓰는 것입니다.당신의 작은 예를 들어 dataframe를 사용

val df = spark.sparkContext.parallelize(Seq (
    (1, "abcd", 12345, "KT10"), 
    (2, "qazx", 98765, "AD12d") 
)).toDF("id", "name", "salary", "tax_code") 

당신이 열 소수의 알려진 이름, 마스크해야하는 경우에, 당신은 간단하게 수행 할 수 있습니다

val mask = Seq("name", "salary") 

df.withColumn("name", lit("*** Masked ***")) 
    .withColumn("salary", lit("*** Masked ***")) 

그렇지 않으면, 당신은 루프를 작성해야합니다 :

+---+--------------+--------------+--------+ 
| id|   name|  salary|tax_code| 
+---+--------------+--------------+--------+ 
| 1|*** Masked ***|*** Masked ***| KT10| 
| 2|*** Masked ***|*** Masked ***| AD12d| 
+---+--------------+--------------+--------+ 
012 :

var df2 = df 
for (col <- mask){ 
    df2 = df2.withColumn(col, lit("*** Masked ***")) 
} 

이 두 가지 방법은이 같은 결과를 줄 것이다

관련 문제