Seq of String에서 DataFrame에 열을 동적으로 추가하려고합니다.
다음은 예입니다. 소스 데이터 프레임은 다음과 같습니다.
+-----+---+----+---+---+
|id | A | B | C | D |
+-----+---+----+---+---+
|1 |toto|tata|titi| |
|2 |bla |blo | | |
|3 |b | c | a | d |
+-----+---+----+---+---+
또한 추가하려는 열 이름이 포함 된 Seq of String이 있습니다. 소스 DataFrame에 열이 이미 존재하는 경우 아래와 같은 차이가 있어야합니다.
Seq는 다음과 같습니다.
val columns = Seq("A", "B", "F", "G", "H")
기대치는 다음과 같습니다.
+-----+---+----+---+---+---+---+---+
|id | A | B | C | D | F | G | H |
+-----+---+----+---+---+---+---+---+
|1 |toto|tata|titi|tutu|null|null|null
|2 |bla |blo | | |null|null|null|
|3 |b | c | a | d |null|null|null|
+-----+---+----+---+---+---+---+---+
지금까지 내가 한 일은 다음과 같습니다.
val difference = columns diff sourceDF.columns
val finalDF = difference.foldLeft(sourceDF)((df, field) => if (!sourceDF.columns.contains(field)) df.withColumn(field, lit(null))) else df)
.select(columns.head, columns.tail:_*)
그러나 더 간단하고 쉬운 방법으로 Spark를 효율적으로 사용하여 이것을 수행하는 방법을 알 수 없습니다 ...
미리 감사드립니다
Seq.diff
, single select
및 map
최종 열 목록을 생성 하는 또 다른 방법은 다음과 같습니다 .
import org.apache.spark.sql.functions.{lit, col}
val newCols = Seq("A", "B", "F", "G", "H")
val updatedCols = newCols.diff(df.columns).map{ c => lit(null).as(c)}
val selectExpr = df.columns.map(col) ++ updatedCols
df.select(selectExpr:_*).show
// +---+----+----+----+----+----+----+----+
// | id| A| B| C| D| F| G| H|
// +---+----+----+----+----+----+----+----+
// | 1|toto|tata|titi|null|null|null|null|
// | 2| bla| blo|null|null|null|null|null|
// | 3| b| c| a| d|null|null|null|
// +---+----+----+----+----+----+----+----+
먼저 우리는 newCols와 df.columns 사이의 차이를 찾습니다 F, G, H
. 다음으로 목록의 각 요소를 lit(null).as(c)
via map
함수로 변환 합니다. 마지막으로 기존 목록과 새 목록을 함께 연결 selectExpr
하여 select
.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다