중첩 필드가있는 기존 데이터 프레임의 스키마를 병합하려고합니다. 내 데이터 프레임의 구조는 다음과 같습니다.apache에서 배열 분해 Explark 데이터 프레임
root
|-- Id: long (nullable = true)
|-- Type: string (nullable = true)
|-- Uri: string (nullable = true)
|-- Type: array (nullable = true)
| |-- element: string (containsNull = true)
|-- Gender: array (nullable = true)
| |-- element: string (containsNull = true)
유형 및성에는 하나의 요소 또는 null 값의 요소 배열이 포함될 수 있습니다. 나는 다음과 같은 코드를 사용하려고 :
var resDf = df.withColumn("FlatType", explode(df("Type")))
을하지만 결과 데이터 프레임의 결과로 나는 유형 열에 대한 null 값을 가지고있는 행을 풀어. 예를 들어, 내가 10 개의 행을 가지고 있고 7 개의 행에 type이 null이고 3 개의 type이 null이 아닌 경우, 결과 데이터 프레임에서 explode를 사용한 후에 단 3 개의 행을 가짐을 의미합니다.
행을 null 값으로 유지하면서 값 배열을 폭발시킬 수 있습니까?
몇 가지 해결 방법이 있지만 한 곳에서 계속 붙어 있습니다.
def customExplode(df: DataFrame, field: String, colType: String): org.apache.spark.sql.Column = {
var exploded = None: Option[org.apache.spark.sql.Column]
colType.toLowerCase() match {
case "string" =>
val avoidNull = udf((column: Seq[String]) =>
if (column == null) Seq[String](null)
else column)
exploded = Some(explode(avoidNull(df(field))))
case "boolean" =>
val avoidNull = udf((xs: Seq[Boolean]) =>
if (xs == null) Seq[Boolean]()
else xs)
exploded = Some(explode(avoidNull(df(field))))
case _ => exploded = Some(explode(df(field)))
}
exploded.get
}
그리고 그건 그냥 같이 사용 후 : 표준 유형의 경우 우리는 다음과 같은 작업을 수행 할 수 그러나
val explodedField = customExplode(resultDf, fieldName, fieldTypeMap(field))
resultDf = resultDf.withColumn(newName, explodedField)
, 나는 다음과 같은 유형의 구조체 유형에 대한 문제가 구조 :
|-- Address: array (nullable = true)
| |-- element: struct (containsNull = true)
| | |-- AddressType: array (nullable = true)
| | | |-- element: string (containsNull = true)
| | |-- DEA: array (nullable = true)
| | | |-- element: struct (containsNull = true)
| | | | |-- Number: array (nullable = true)
| | | | | |-- element: string (containsNull = true)
| | | | |-- ExpirationDate: array (nullable = true)
| | | | | |-- element: timestamp (containsNull = true)
| | | | |-- Status: array (nullable = true)
| | | | | |-- element: string (containsNull = true)
DEA가 null의 경우
우리가 어떻게 스키마의 종류를 처리 할 수 있습니까?
미리 감사드립니다.
P. 측면보기를 사용하려고했지만 결과는 같습니다.
미안하지만,이 솔루션을 시도 할 때 다음 예외가 있습니다. java.lang.UnsupportedOperationException. explode (df ("Type"))를 단지 약간의 값으로 대체하면 정상적으로 작동합니다. 함수가 열을 값으로 – Artem
@Artem으로 분해 된 열을 지원하지 않을 때, 당신은 옳다. 나는 미안하다. '노동 조합 '이 당신을위한 선택인가? unionAll (df.withColumn ("FlatType", explode ($ "Type")))' –
yes df.where ($ "Type".isNull) .withColumn ("FlatType", lit (null) , 고마워,이 옵션에 대해 생각했지만 스키마를 병합하기위한 일반 알고리즘을 구축 중이며 연합이 실제로 느릴 수도 있습니다. 더 나은 해결책을 찾고 싶지만 노동 조합은 나를위한 백업 옵션입니다. – Artem