1
votes

Comment trouver des valeurs distinctes de plusieurs colonnes dans Spark

J'ai un RDD et je veux trouver des valeurs distinctes pour plusieurs colonnes.

Exemple:

Row (col1 = a, col2 = b, col3 = 1), Row ( col1 = b, col2 = 2, col3 = 10)), Row (col1 = a1, col2 = 4, col3 = 10)

Je voudrais trouver une carte: p>

def to_uniq_vals(row):
   return [(k,v) for k,v in row.items()]

rdd.flatMap(to_uniq_vals).distinct().collect()

Le dataframe peut-il aider à le calculer plus rapidement / plus simplement?

Mise à jour:

Ma solution avec RDD était:

col1=[a,b,a1]
col2=[b,2,4]
col3=[1,10]

Merci


4 commentaires

Toutes les valeurs uniques correspondent-elles à la mémoire du pilote?


plus vite que quoi? comment le calculeriez-vous dans RDD?


@Yaron a mis à jour la question avec une option pour calculer des valeurs distinctes


@ ollik1 oui ils le font


3 Réponses :


-3
votes

Peut-être que si j'ai bien compris votre question, vous pouvez la convertir en dataframe et obtenir les valeurs distinctes de chaque colonne.

>>> rdd.collect()
[Row(col1='a', col2='b', col3=1), Row(col1='b', col2=2, col3=10), Row(col1='a1', col2=4, col3=10)]
>>> df=rdd.toDF()
19/06/02 18:13:25 WARN ObjectStore: Failed to get database global_temp, returning NoSuchObjectException
+----+----+----+
|col1|col2|col3|
+----+----+----+
|   a|   b|   1|
|   b|   2|  10|
|  a1|   4|  10|
+----+----+----+

>>> df.select(df['col1']).distinct().show()
+----+
|col1|
+----+
|  a1|
|   b|
|   a|
+----+

>>> df.select(df['col2']).distinct().show()
+----+
|col2|
+----+
|   b|
|   4|
|   2|
+----+

>>> df.select(df['col3']).distinct().show()
+----+
|col3|
+----+
|   1|
|  10|
+----+


2 commentaires

Cela signifiera analyser les données pour chaque colonne, et j'en ai ~ 30, je préfère le faire en un seul passage.


Cette approche n'est utile qu'en cas de petit nombre de colonnes.



2
votes

J'espère avoir bien compris votre question; Vous pouvez essayer ce qui suit:

+---------------+---------------+---------------+
|collect_set(_1)|collect_set(_2)|collect_set(_3)|
+---------------+---------------+---------------+
|     [a1, b, a]|      [1, 2, 4]|        [1, 10]|
+---------------+---------------+---------------+

Résultats:

import org.apache.spark.sql.{functions => F}
val df = Seq(("a", 1, 1), ("b", 2, 10), ("a1", 4, 10))
df.select(F.collect_set("_1"), F.collect_set("_2"), F.collect_set("_3")).show

Le code ci-dessus devrait être plus efficace que le select distinct colonne par colonne pour plusieurs raisons:

  1. Moins d'allers-retours entre les travailleurs et les hôtes
  2. La déduplication doit être effectuée localement sur le nœud de calcul avant la déduplication entre les nœuds de calcul.

J'espère que cela vous aidera!


0 commentaires

4
votes

Vous pouvez utiliser la suppression des doublons, puis sélectionner les mêmes colonnes. Ce n'est peut-être pas le moyen le plus efficace, mais tout de même un moyen décent:

df.dropDuplicates("col1","col2", .... "colN").select("col1","col2", .... "colN").toJSON

** Fonctionne bien avec Scala


0 commentaires