1
votes

Spark [Scala]: vérifier si toutes les lignes d'un DataFrame plus petit existent dans le DataFrame plus grand

J'ai deux DataFrames, avec le même schéma (mais +100 colonnes):

  1. Petite taille: 1 000 lignes
  2. Taille plus grande: 90000 lignes

Comment vérifier que chaque ligne en 1 existe en 2? Quelle est la "manière Spark" de faire cela? Dois-je utiliser map et ensuite la traiter au niveau Row ; ou j'utilise join puis j'utilise une sorte de comparaison avec le DataFrame de petite taille?


3 commentaires

Si vous voulez une jointure, utilisez simplement une jointure innre et comptez le nombre de lignes dans smallDf et joinsDf


@BlueSheepToken cela vous dérange-t-il de publier votre réponse?


Je vais, je pensais juste que le sauf un pourrait être plus clair


3 Réponses :


3
votes

Vous pouvez utiliser sauf , qui renvoie toutes les lignes du premier ensemble de données qui ne sont pas présentes dans le deuxième

smaller.except(bigger).isEmpty()


4 commentaires

Vous devez éviter le décompte pour vérifier si un dataframe est vide. Sauf que, je suis totalement d'accord avec la réponse!


Oui, c'est vrai, il semble que depuis 2.4 il y a juste isEmpty


Assez étrange, la taille du compte est plus grande que la taille d'une plus petite trame de données. Cela ne peut pas être vrai? Dans le pire des cas, nous devrions avoir 1000 comme décompte.


Peut-être que c'est plus grand, sauf (plus petit)? :)



1
votes

Je le ferais avec join, probablement

 entrez la description de l'image ici

Cette jointure vous donnera toutes les lignes qui sont dans un petit bloc de données mais qui manquent dans grande trame de données. Ensuite, vérifiez simplement s'il s'agit d'une taille nulle ou non.

Code:

+---+---+---+---+---+---+---+---+---+---+
| cA| cB| cH| cI| cJ| cA| cB| cC| cD| cE|
+---+---+---+---+---+---+---+---+---+---+
|  C|ghi|  a|  c|  ?|  C|ghi|0.2|0.2|  1|
|  A|abc|  a|  b|  ?|  A|abc|0.1|0.0|  0|
+---+---+---+---+---+---+---+---+---+---+

Sortie:

val seq1 = Seq(
  ("A", "abc", 0.1, 0.0, 0),
  ("B", "def", 0.15, 0.5, 0),
  ("C", "ghi", 0.2, 0.2, 1),
  ("D", "jkl", 1.1, 0.1, 0),
  ("E", "mno", 0.1, 0.1, 0)
)

val seq2 = Seq(
  ("A", "abc", "a", "b", "?"),
  ("C", "ghi", "a", "c", "?")
)


val df1 = ss.sparkContext.makeRDD(seq1).toDF("cA", "cB", "cC", "cD", "cE")
val df2 = ss.sparkContext.makeRDD(seq2).toDF("cA", "cB", "cH", "cI", "cJ")


df2.join(df1, df1("cA") === df2("cA"), "leftOuter").show


1 commentaires

Pourriez-vous s'il vous plaît également ajouter un code Spark / Scala à votre réponse? Merci.



1
votes

Vous pouvez joindre le DF en interne et compter pour vérifier s'il y a une différence.

def isIncluded(smallDf: Dataframe, biggerDf: Dataframe): Boolean = {
  val keys = smallDf.columns.toSeq

  val joinedDf = smallDf.join(biggerDf, keys) // You might want to broadcast smallDf for performance issues
  joinedDf.count == smallDf
}

Cependant, je pense que la méthode except est plus claire. Je ne suis pas sûr des performances (cela pourrait être juste une jointure en dessous)


0 commentaires