164 votes

Afficher des valeurs de colonne distinctes dans un dataframe Pyspark

Avec le dataframe pyspark, comment faire l'équivalent de df['col'].unique() dans Pandas.

Je veux répertorier toutes les valeurs uniques dans une colonne d'un dataframe pyspark.

Je ne veux pas faire la méthode SQL (registertemplate puis requête SQL pour les valeurs distinctes).

Je ne veux pas non plus utiliser groupby puis countDistinct, je préfère vérifier les VALEURS distinctes dans cette colonne.

319voto

Pabbati Points 671

Cela devrait aider à obtenir des valeurs distinctes d'une colonne :

df.select('column1').distinct().collect()

Notez que .collect() n'a pas de limite intégrée sur le nombre de valeurs qu'il peut renvoyer, donc cela pourrait être lent - utilisez plutôt .show() ou ajoutez .limit(20) avant .collect() pour gérer cela.

0 votes

Ce code renvoie des données qui ne sont pas itérables, c'est-à-dire que je vois les données distinctes mais je ne suis pas capable de les itérer dans le code. Y a-t-il un autre moyen qui me permet de le faire? J'ai essayé d'utiliser toPandas() pour le convertir en dataframe Pandas puis obtenir l'itérable avec des valeurs uniques. Cependant, je rencontre un message d'erreur disant '' Pandas non trouvé''.

11 votes

@Abhi: au lieu de .show(), faites un .collect(), de cette façon vous obtiendrez un itérable de toutes les valeurs distinctes de cette colonne particulière. Mais assurez-vous que votre nœud maître a suffisamment de mémoire pour conserver ces valeurs uniques, car collect poussera toutes les données demandées (dans ce cas les valeurs uniques de la colonne) vers le nœud maître :)

1 votes

@Satya j'ai édité votre commentaire dans la réponse, merci

111voto

eddies Points 1728

Supposons que nous travaillons avec la représentation suivante des données (deux colonnes, k et v, où k contient trois entrées, deux uniques:

+---+---+
|  k|  v|
+---+---+
|foo|  1|
|bar|  2|
|foo|  3|
+---+---+

Avec un dataframe Pandas:

import pandas as pd
p_df = pd.DataFrame([("foo", 1), ("bar", 2), ("foo", 3)], columns=("k", "v"))
p_df['k'].unique()

Cela renvoie un ndarray, c'est-à-dire array(['foo', 'bar'], dtype=object)

Vous avez demandé une "alternative de dataframe pyspark pour pandas df['col'].unique()". Maintenant, étant donné le dataframe Spark suivant:

s_df = sqlContext.createDataFrame([("foo", 1), ("bar", 2), ("foo", 3)], ('k', 'v'))

Si vous voulez le même résultat avec Spark, c'est-à-dire un ndarray, utilisez toPandas():

s_df.toPandas()['k'].unique()

Alternativement, si vous n'avez pas besoin d'un ndarray spécifiquement et que vous voulez juste une liste des valeurs uniques de la colonne k:

s_df.select('k').distinct().rdd.map(lambda r: r[0]).collect()

Enfin, vous pouvez également utiliser une compréhension de liste comme suit:

[i.k for i in s_df.select('k').distinct().collect()]

1 votes

Salut eddies, la dernière ligne de code distinct().map() n'a pas fonctionné pour moi. Erreur : AttributeError: l'objet 'DataFrame' n'a pas d'attribut 'map'. Je suis sur spark 2.0. Et pour la fonction toPandas, je ne dirais pas que c'est une alternative, elle convertit d'abord le dataframe spark en dataframe pandas puis effectue des opérations pandas dessus.

1 votes

Salut satya. Je viens de mettre à jour la réponse en ajoutant un appel .rdd après distinct(). Ça fonctionnait sans cela dans Spark 1.6.2, mais je viens de confirmer que la réponse modifiée fonctionne aussi dans Spark 2.0.0.

5 votes

Pourquoi essayer d'éviter les opérations de dataframe Spark en convertissant en un dataframe pandas (douleur si c'est gigantesque) ou en utilisant des opérations RDD lorsque les dataframes Spark sont parfaitement capables de le faire? voir ci-dessous la réponse de @Pabbati

21voto

seufagner Points 458

Vous pouvez utiliser df.dropDuplicates(['col1','col2']) pour obtenir uniquement des lignes distinctes en fonction de colX dans le tableau.

2 votes

@seufagner-oui, je peux faire un df.dropDuplictes(['col1']) pour voir (marquer VOIR) les valeurs uniques, mais sans une collect(to_rdd ou to pandas DF ensuite df['col'].unique()), je ne peux pas obtenir la liste des valeurs uniques. Merci pour la suggestion.

0 votes

L'utilisateur n'a pas demandé comment afficher des valeurs non dupliquées.. Il voulait juste obtenir une liste de tous les éléments uniques/distincts, qui inclut également les doublons !

0 votes

C'est correct parce que df.select().collect() est une opération coûteuse qui peut entraîner une erreur d'échec de scène.

14voto

Nidhi Points 166

Si vous voulez voir les valeurs distinctes d'une colonne spécifique dans votre dataframe, il vous suffit d'écrire le code suivant. Il affichera les 100 valeurs distinctes (si 100 valeurs sont disponibles) pour la colonne colname dans le dataframe df.

df.select('colname').distinct().show(100, False)

Si vous souhaitez effectuer une opération spéciale sur les valeurs distinctes, vous pouvez sauvegarder les valeurs distinctes dans un vecteur :

a = df.select('colname').distinct()

11voto

Hari Baskar Points 326

collect_set peut aider à obtenir des valeurs uniques à partir d'une colonne donnée de pyspark.sql.DataFrame:

df.select(F.collect_set("column").alias("column")).first()["column"]

0 votes

Je suis d'accord pour utiliser collect_set, mais je pense que la méthode suivante serait plus propre: df.agg(F.collect_set("column")).collect()[0][0]

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X