복붙노트

[SCALA] 무엇 스파크의`unionAll``DataFrame`으로 잘못된 것입니다?

SCALA

무엇 스파크의`unionAll``DataFrame`으로 잘못된 것입니다?

다음 코드를 스파크 1.5.0을 사용하여 주어진, 나는 그들의 열 이름에 따라 노조 DataFrames에 unionAll를 기대합니다. 코드에서 나는 SparkContext 사우스 캐롤라이나에 전달하는 일부 FunSuite을 사용하고 있습니다 :

object Entities {

  case class A (a: Int, b: Int)
  case class B (b: Int, a: Int)

  val as = Seq(
    A(1,3),
    A(2,4)
  )

  val bs = Seq(
    B(5,3),
    B(6,4)
  )
}

class UnsortedTestSuite extends SparkFunSuite {

  configuredUnitTest("The truth test.") { sc =>
    val sqlContext = new SQLContext(sc)
    import sqlContext.implicits._
    val aDF = sc.parallelize(Entities.as, 4).toDF
    val bDF = sc.parallelize(Entities.bs, 4).toDF
    aDF.show()
    bDF.show()
    aDF.unionAll(bDF).show
  }
}

산출:

+---+---+
|  a|  b|
+---+---+
|  1|  3|
|  2|  4|
+---+---+

+---+---+
|  b|  a|
+---+---+
|  5|  3|
|  6|  4|
+---+---+

+---+---+
|  a|  b|
+---+---+
|  1|  3|
|  2|  4|
|  5|  3|
|  6|  4|
+---+---+

왜 결과는 "B"와 "A"열 대신 열 이름에 열 기지를 정렬의 혼합이 포함되어 있습니까? 심각한 버그 같은 소리!?

해결법

  1. ==============================

    1.그것은 모든 벌레처럼 보이지 않는다. 당신이 참조 표준 SQL 동작입니다과 PostgreSQL, MySQL은, 오라클, MS SQL을 포함한 모든 주요 RDMBS는 정확히 동일하게 동작합니다. 당신은 이름과 연결 SQL 바이올린 예를 찾을 수 있습니다.

    그것은 모든 벌레처럼 보이지 않는다. 당신이 참조 표준 SQL 동작입니다과 PostgreSQL, MySQL은, 오라클, MS SQL을 포함한 모든 주요 RDMBS는 정확히 동일하게 동작합니다. 당신은 이름과 연결 SQL 바이올린 예를 찾을 수 있습니다.

    PostgreSQL의 설명서를 인용 :

    설정 작업의 첫 번째 테이블을 제외한 열 이름은, 단순히 무시됩니다.

    기본 빌딩 블록은 튜플이다이 문제는 직접 관계 대수를 형성되어 있습니다. 튜플은 튜플의 두 세트의 조합을 주문하고 있기 때문에 동일합니다 당신이 여기 얻을 출력 (처리 중복을 무시).

    당신이 이름을 사용하여 일치 할 경우, 당신은 이런 식으로 뭔가를 할 수 있습니다

    import org.apache.spark.sql.DataFrame
    import org.apache.spark.sql.functions.col
    
    def unionByName(a: DataFrame, b: DataFrame): DataFrame = {
      val columns = a.columns.toSet.intersect(b.columns.toSet).map(col).toSeq
      a.select(columns: _*).unionAll(b.select(columns: _*))
    }
    

    그것으로 열을 대체하기에 충분해야 모두 이름과 유형을 확인하려면 :

    a.dtypes.toSet.intersect(b.dtypes.toSet).map{case (c, _) => col(c)}.toSeq
    
  2. ==============================

    2.이 문제는 spark2.3에 고정지고 있습니다. 그들은 데이터 세트에서 unionByName의 지원을 추가합니다.

    이 문제는 spark2.3에 고정지고 있습니다. 그들은 데이터 세트에서 unionByName의 지원을 추가합니다.

    https://issues.apache.org/jira/browse/SPARK-21043
    
  3. ==============================

    3.어떤 문제 / 버그 - 당신은 매우 밀접 경우 클래스 B를 준수하면 당신은 명확하지 않습니다. 케이스 클래스 A는 -> 당신이 순서를 언급 한 (A, B) 및 케이스 클래스 B -> 당신이 순서 언급 한 (B를 A) --->이이 순서에 따라 예상된다

    어떤 문제 / 버그 - 당신은 매우 밀접 경우 클래스 B를 준수하면 당신은 명확하지 않습니다. 케이스 클래스 A는 -> 당신이 순서를 언급 한 (A, B) 및 케이스 클래스 B -> 당신이 순서 언급 한 (B를 A) --->이이 순서에 따라 예상된다

    케이스 클래스 A (A : INT, B : INT)   케이스 클래스 B (b : INT, A : INT)

    감사, Subbu

  4. ==============================

    4.SPARK-9813에서 설명하고있는 바와 같이, 그것은 한 데이터 유형과 열의 개수가 같은에서 프레임만큼 보인다는 unionAll 작업이 작동합니다. 추가 논의에 대한 의견을 참조하십시오.

    SPARK-9813에서 설명하고있는 바와 같이, 그것은 한 데이터 유형과 열의 개수가 같은에서 프레임만큼 보인다는 unionAll 작업이 작동합니다. 추가 논의에 대한 의견을 참조하십시오.

  5. ==============================

    5.unionByName를 사용 :

    unionByName를 사용 :

    문서에서 발췌 :

    DEF unionByName (기타 : 데이터 세트 [T]) 데이터 세트 [T]

    val df1 = Seq((1, 2, 3)).toDF("col0", "col1", "col2")
    val df2 = Seq((4, 5, 6)).toDF("col1", "col2", "col0")
    df1.union(df2).show
    
    // output:
    // +----+----+----+
    // |col0|col1|col2|
    // +----+----+----+
    // |   1|   2|   3|
    // |   4|   5|   6|
    // +----+----+----+
    
  6. from https://stackoverflow.com/questions/32705056/what-is-going-wrong-with-unionall-of-spark-dataframe by cc-by-sa and MIT license