2016-12-30 11 views
1

を同じデータフレームを結ぶ双方向の関係を削除する私は最近、スパークScalaの上で開発を開始し、そして私が持っているし、私は同じテーブルの2つのデータフレームに参加しようとして問題が発生しました:スパークScalaの

データフレームAを:

Column Names:{AID, AName} 
Data:{1:a, 2:b, 3:c, 4:d} 

DATAFRAME B:

Column Names {BID, AID, BName} 
Data: {AB232:1:"Mark", AC32D:1:"Sarah", D2123:1:"John", S23DS:2:"Matthew"} 

私は、私が取得する必要があり、この場合には、相互に接続されているすべての人々の名前を取得する必要があります:

:私はデータフレームBを(ここではB1とB2がBのインスタンスである)に参加しようとすると、代わりに

"Mark" - "Sarah" , "Mark" - "John", "Sarah"- "John" 

B1.joinWith(B2, B1("AID") === B2("AID) && B1("BID") =!= B2("BID")); 

この結合後、結果の表を選択して両方のデータフレームからBNameを取得します。

私が得る結果は次のとおりです。私は双方向の関係を避けることができるように既にデータが両方の列に存在する場合、私は確認することができた方法は

"Mark" - "Sarah" ,"Sarah"- "Mark", "Mark" - "John", "John" - "Mark", "Sarah"- "John", "John"- "Sarah". 

ありますか?あなたが唯一のB2.BIDB1.BIDその後、大きいレコードを一致するように、BIDを比較すること<の代わり=!=を使用することができます

答えて

1

、各試合の故に唯一の「インスタンス」が参加している:

B1.joinWith(B2, B1("AID") === B2("AID") && B1("BID") < B2("BID")).show() 
// +---------------+---------------+ 
// |_1    |_2    | 
// +---------------+---------------+ 
// |[AB232,1,Mark] |[D2123,1,John] | 
// |[AB232,1,Mark] |[AC32D,1,Sarah]| 
// |[AC32D,1,Sarah]|[D2123,1,John] | 
// +---------------+---------------+ 

EDITもちろん、あなたもそのままご参加残すことができ、そしてあとがきフィルタ:として

B1.joinWith(B2, B1("AID") === B2("AID") && B1("BID") =!= B2("BID")) 
    .filter($"_1.BID" < $"_2.BID") 

を210が指摘したように、それは速いかもしれません - あなたの実際のデータで両方を試してみてください:)

+0

参加した後でフィルタを行う方が良いですか?現在の方法では、結合でフィルタリングによるクロス結合が使用されます。 '==='のみで結合すると、ソート/マージ結合が使用されます –

+0

良い点 - それは確かではありませんが、私はCatalystがこの最適化を行うことができると思います。これらの小さなデータセットとSpark 2.0.1を使用して、両方の実装で同じ物理的な計画が見られます。 –

+0

[OK]を、最適化されている可能性があります;)いくつかの時間前に私は '==='のみ最適化することができます、多分いくつかの変更があったことを読む:) –

関連する問題