2017-10-18 7 views
-1

私は4列を含むデータフレームを持っています。カスタマイズされたユーザー定義集約個別関数の作成方法

データフレームのサンプル行のデータの2種類があり

id1 id2 id3 id4 
--------------- 
a1 a2 a3 a4 
b1 b2 b3 b4 
b1 b2 b3 b4 
c1 c2 c3 c4 
    b2  
c1 
     a3 
      a4 
c1 
     d4 

いずれかのすべての列は、データ又は1つの列のみを有します。

行間の値を比較しながら、すべての列に対して別個の機能を実行したい場合は、行内に存在する値だけを比較し、NULL値は考慮しません。

出力データフレームは、私がスパークにUDAFの複数の例を見てきました

id1 id2 id3 id4 
a1 a2 a3 a4 
b1 b2 b3 b4 
c1 c2 c3 c4 
     d4 

でなければなりません。しかし、変更することはできません。

+0

は、なぜあなたはすべての4つの列のフィルタ方式を使用していませんか? –

+0

フィルターはどのように役立ちますか? – Kaushal

+0

下記の私の答えをご覧ください –

答えて

1

あなたは

df.filter($"id1" =!= "" && $"id2" =!= "" && $"id3" =!= "" && $"id4" =!= "") 

以下のようにすべての列のfilterを使用することができますし、最終的なデータフレームを取得する必要があります。

上記のコードは、静的な4列のデータフレーム用です。 4つ以上のカラムがある場合、メソッドが多すぎるロジックチェックを書く必要があるため、メソッドが忙しくなります。

それに対する解決策は、私は答えはそれdropDuplicatesを利用することが可能である

+0

ansのおかげで、まず最初に、ある行の値が別の行にあるかどうかをチェックする必要があります。変更された質問を参照してください。 – Kaushal

1

役立つことを願う

import org.apache.spark.sql.functions._ 
def checkIfNull = udf((co : mutable.WrappedArray[String]) => !(co.contains(null) || co.contains(""))) 
df.filter(checkIfNull(array(df.columns.map(col): _*))).show(false) 

以下のようにudf機能を使用することですが、これを解決するに依存するためです、答えはhereです。しかし、あまり効率的ではありません。効率的なソリューションが必要です。

まず、すべての重複をdistinct()で削除してから、各列ごとに繰り返し順序を入れて重複を削除します。列は降順で並べられ、nullsが最後に配置されます。 4つの静的な列と

例:

val df2 = df.distinct() 
    .orderBy($"id1".desc).dropDuplicates("id1") 
    .orderBy($"id2".desc).dropDuplicates("id2") 
    .orderBy($"id3".desc).dropDuplicates("id3") 
    .orderBy($"id4".desc).dropDuplicates("id4") 
+0

ありがとうございますansですが、最初に私は別の行に存在するかどうか、それ以外の場合は、その行を保持するだけではない行の値を確認する必要があります。変更された質問を参照してください。 – Kaushal

+0

空の列には 'null'のみが含まれ、' "" '文字列はありません – Kaushal

+0

@Kaushal可能な最良の解決法ではないと思われる答えで更新されました。 – Shaido

関連する問題