web-dev-qa-db-fra.com

Différence entre Spark RDD take (1) et first ()

Je pensais que rdd.take(1) et rdd.first() sont exactement les mêmes. Cependant, j'ai commencé à me demander si cela est vraiment vrai après que mon collègue m'a indiqué la documentation d'officialisation de Spark sur RDD :

first () : Renvoie le premier élément de ce RDD.

take (num) : Prenez les premiers éléments num du RDD. Il fonctionne en analysant d'abord une partition et en utilisant les résultats de cette partition pour estimer le nombre de partitions supplémentaires nécessaires pour respecter la limite.

Mes questions sont:

  1. L'implémentation sous-jacente de first() est-elle la même que take(1)?
  2. Supposons que rdd1 Et rdd2 Sont construits à partir du même csv, puis-je supposer en toute sécurité que rdd1.take(1) et rdd2.first() will toujours retourne le même résultat, c'est-à-dire la première ligne du csv? Que faire si rdd1 Et rdd2 Sont partitionnés différemment?
11
Ida

Infact first est implémenté en termes de take.

Ce qui suit est tiré de la source de spark de RDD.scala . first appelle take(1) et retourne le premier élément s'il est trouvé.

  def first(): T = withScope {
    take(1) match {
      case Array(t) => t
      case _ => throw new UnsupportedOperationException("empty collection")
    }
  }

take(num) essaie de prendre des éléments num à partir de la 0ème partition de RDD (si vous considérez les index basés sur 0). Le comportement de take (1) et first sera donc identique.

Même le guide de programmation spark le confirme.

À propos de votre deuxième question: cela dépend de ce que vous voulez dire lorsque vous dites partitionné différemment. Si vous appelez sc.textFile("/path/to/file") avec ou sans numPartitions, cela n'aurait pas d'importance car la 0ème partition sera toujours la 0ème partition. Donc oui, vous pouvez supposer qu'ils auront le même premier élément.

EDIT: Les partitions en RDD sont ordonnées, la première ligne physique de votre CSV se retrouvera dans la 0ème partition sur RDD. Et take(1) et first les deux renverront cette première ligne de la 0ème partition.

18
Pranav Shukla

Non, les deux ne sont pas identiques.

rdd.first() renverra le premier élément de ce RDD tandis que rdd.take(1) renverra un tableau qui n'aura que le premier élément.

  1. L'implémentation sous-jacente de first () est-elle la même que take (1)?

Ans: En termes d'implémentation first () appelle take (1) en interne et retourne le premier et le seul élément du tableau retourné par take (1). Extrait de la classe org.Apache.spark.rdd.RDD

  /**
   * Return the first element in this RDD.
   */
  def first(): T = withScope {
    take(1) match {
      case Array(t) => t
      case _ => throw new UnsupportedOperationException("empty collection")
    }
  }
  1. Supposons que rdd1 et rdd2 sont construits à partir du même csv, puis-je supposer en toute sécurité que rdd1.take (1) et rdd2.first () renverront toujours le même résultat, c'est-à-dire la première ligne du csv? Et si rdd1 et rdd2 sont partitionnés différemment?

Rép: Oui, vous pouvez supposer que le partitionnement ne change pas l'ordre dans lequel l'entrée a été lue.

5
Amit Kumar

Donc, il semble que les deux soient identiques, mais nous avons des différences.

1.Lorsque nous lisons les données du fichier, il s'agit par défaut d'un RDD, et un RDD possède à la fois les attributs first() et take().
2.L'attribut first() renvoie un objet de type ligne tandis que take() renvoie un type de liste.

Mais dès que nous convertissons notre RDD en DataFrame en utilisant .toDF(), nous n'avons pas l'attribut first() sur ce DF.

J'espère que cela clarifiera davantage les concepts.

Voir l'image pour plus de clarté

0
Gaurav Sehrawat