2015-09-21 32 views
13

使用Spark 1.5.0並給出以下代碼,我希望unionAll根據它們的列名稱來聯合DataFrame。在代碼中,我使用了一些FunSuite傳遞在SparkContext sc這是怎麼回事錯`星火unionAll``DataFrame`?

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」 和 「一」列,而不是根據列名對齊列?聽起來像一個嚴重錯誤!?

回答

26

它看起來不像一個錯誤。你所看到的是標準的SQL行爲,每個主要的RDMBS,包括PostgreSQLMySQL,OracleMS SQL表現完全一樣。您會發現SQL Fiddle示例與名稱鏈接。

引述PostgreSQL manual

爲了計算集,交集或兩個查詢的差異,這兩個查詢必須是「聯合兼容」的,這意味着它們將返回相同的列數和相應的列具有兼容的數據類型

列名稱(不包括集合操作中的第一個表格)被忽略。

此行爲直接來自關係代數,其中基本構建塊是元組。由於元組是有序的,因此兩組元組的聯合是等價的(忽略重複處理)到你得到的輸出。

如果你想使用的名字相匹配,你可以做這樣的事情

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: _*)) 
} 

要檢查這兩個名字和類型也應該足夠,以取代columns

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

Thx!這不是一個真正的問題,至少在我的情況下,列順序需要改變。儘管如此,將Scala文檔中的這些信息有助於避免錯誤。不過,我會提供一個'unionAllVia ColumnNames'重新排列列,使得它們在1相匹配:1的方式,如果可能的。 –

+0

@MartinSenne其實Scala的Google文檔提供了足夠的信息來獲得在接受的答案所描述的具體行爲。也就是說, '這相當於UNION ALL在SQL' – kasur

+0

@MartinSenne您指出行的排序。這應該在文檔中提到。 –

0

正如在SPARK-9813中所討論的那樣,只要跨幀的數據類型和列數相同,unionAll操作應該可以工作。請參閱評論以獲取更多討論。

+1

如果列的順序不同,那麼呢? – sau

2

這個問題在spark2.3中得到修復。他們在數據集中添加對unionByName的支持。

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