2017-10-18 33 views
-1

J'ai une base de données qui contient 4 colonnes.comment créer une fonction distincte personnalisée définie par l'utilisateur

exemple de trame de données

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 

Il existe 2 types de données dans une rangée, soit toutes les colonnes ont des données ou une seule colonne. Je souhaite effectuer une fonction distincte sur toutes les colonnes, par exemple, en comparant les valeurs entre les lignes, je ne comparerai que la valeur présente dans une ligne et je ne considérerai pas les valeurs nulles.

sortie dataframe doit être

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

J'ai regardé plusieurs exemples de UDAF à étincelle. Mais pas en mesure de modifier selon.

+0

pourquoi utilisez-vous pas la méthode de filtrage sur les quatre colonnes? –

+0

Comment le filtre peut m'aider? – Kaushal

+0

s'il vous plaît voir ma réponse ci-dessous –

Répondre

1

vous pouvez utiliser filter pour toutes les colonnes comme ci-dessous

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

et vous devriez obtenir votre dataframe finale.

Le code ci-dessus est destiné aux données statiques à quatre colonnes. Si vous avez plus de quatre colonnes au-dessus de la méthode deviendrait trépidante car vous auriez à écrire trop de vérifications logiques.

la solution à ce serait d'utiliser une fonction udf comme ci-dessous

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) 

J'espère que la réponse est utile

+0

Merci pour les ans mais d'abord j'ai besoin de vérifier la valeur de la ligne est présente sur d'autres lignes ou non, puis seulement le retirer sinon conserver cette ligne. voir la question modifiée. – Kaushal

1

Il est possible de profiter de cette dropDuplicates est l'ordre dépend de résoudre ce problème, voir la réponse here. Cependant, ce n'est pas très efficace, il devrait y avoir une solution plus efficace.

Supprimez d'abord tous les doublons avec distinct(), puis itérez-les par colonne et déposez-les en double. Les colonnes sont classées par ordre décroissant en tant que nulls puis seront mises en dernier.

Exemple avec quatre colonnes statiques:

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

Merci pour les ans mais d'abord j'ai besoin de vérifier la valeur de la ligne est présente sur d'autres lignes ou non, puis retirez-le sinon conserver cette ligne. voir la question modifiée. – Kaushal

+0

Et les colonnes vides contiennent 'null' seulement, pas de' '' '' chaîne – Kaushal

+0

@Kaushal Mis à jour avec une réponse qui fonctionnera, cependant, probablement pas la meilleure solution possible. – Shaido