2017-04-23 61 views
0

假設我有兩個Spark SQL數據框AB。我想從A中的項目中減去B中的項目,同時保留A中的重複項目。Spark:減去數據幀但保留重複值

我按照說明使用DataFrame.except(),我發現在另一個StackOverflow問題("Spark: subtract two DataFrames"),但該函數刪除原始數據幀A的所有重複項。

作爲概念上的例子,如果我有兩個dataframes:

words  = [the, quick, fox, a, brown, fox] 
stopWords = [the, a] 

然後我想輸出是,以任何順序:

words - stopWords = [quick, brown, fox, fox] 

我觀察到RDD功能subtract()保留重複,但Spark-SQL函數except()刪除結果數據框中的重複項。我不明白爲什麼except()輸出只產生唯一的值。

這裏是一個完整的演示:

// --------------------------------------------------------------- 
// EXAMPLE USING RDDs 
// --------------------------------------------------------------- 
var wordsRdd = sc.parallelize(List("the", "quick", "fox", "a", "brown", "fox")) 
var stopWordsRdd = sc.parallelize(List("a", "the")) 

var wordsWithoutStopWordsRdd = wordsRdd.subtract(stopWordsRdd) 
wordsWithoutStopWordsRdd.take(10) 
// res11: Array[String] = Array(quick, brown, fox, fox) 

// --------------------------------------------------------------- 
// EXAMPLE USING DATAFRAMES 
// --------------------------------------------------------------- 
var wordsDf = wordsRdd.toDF() 
var stopWordsDf = stopWords.toDF() 
var wordsWithoutStopWordsDf = wordsDf.except(stopWordsDf) 

wordsWithoutStopWordsDf.show(10) 
// +-----+ 
// |value| 
// +-----+ 
// | fox| 
// |brown| 
// |quick| 
// +-----+ 

我想保留重複,因爲我生成頻數表。

任何幫助,將不勝感激。

+0

我敢打賭,這是因爲它使用了'Set'而不是'List'。除了你正在尋找的是一個'join'。 –

+0

@AlbertoBonsanto:一個'join'執行一個交集,對吧?結果將是「A」和「B」中的值。我想要他們之間的差異,而不是路口。 – stackoverflowuser2010

+0

取決於連接的類型。順便檢查一下我的答案 –

回答

1
val words = sc.parallelize(List("the", "quick", "fox", "a", "brown", "fox")).toDF("id") 
val stopwords = sc.parallelize(List("a", "the")).toDF("id") 


words.join(stopwords, words("id") === stopwords("id"), "left_outer") 
    .where(stopwords("id").isNull) 
    .select(words("id")).show() 

輸出是:

+-----+ 
| id| 
+-----+ 
| fox| 
| fox| 
|brown| 
|quick| 
+-----+ 
+0

這種左外連接方式確實很光滑。謝謝。 – stackoverflowuser2010