Zeigen Sie unterschiedliche Spaltenwerte im pyspark-Datenrahmen an: Python

81

Bitte schlagen Sie eine pyspark-Datenrahmenalternative für Pandas vor df['col'].unique().

Ich möchte alle eindeutigen Werte in einer pyspark-Datenrahmenspalte auflisten.

Nicht der SQL-Typ (Registertemplate, dann SQL-Abfrage nach bestimmten Werten).

Auch brauche ich nicht groupby->countDistinct, stattdessen möchte ich unterschiedliche WERTE in dieser Spalte überprüfen.

Satya
quelle

Antworten:

83

Nehmen wir an, wir arbeiten mit der folgenden Darstellung von Daten (zwei Spalten kund v, wo kdrei Einträge enthalten, zwei eindeutige:

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

Mit einem Pandas-Datenrahmen:

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

Dies gibt ein zurück ndarray, dharray(['foo', 'bar'], dtype=object)

Sie haben nach einer "pyspark-Datenrahmenalternative für pandas df ['col']. Unique ()" gefragt. Angesichts des folgenden Spark-Datenrahmens:

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

Wenn Sie dasselbe Ergebnis von Spark wünschen , dh an ndarray, verwenden Sie toPandas():

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

Alternativ, wenn Sie keine ndarrayspezielle benötigen und nur eine Liste der eindeutigen Werte der Spalte wünschen k:

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

Schließlich können Sie ein Listenverständnis auch wie folgt verwenden:

[i.k for i in s_df.select('k').distinct().collect()]
Wirbel
quelle
1
Hallo Wirbel, die letzte Codezeile different (). Map () hat bei mir nicht funktioniert. Fehler: AttributeError: Das Objekt 'DataFrame' hat kein Attribut 'map'. Ich bin auf Spark 2.0. Und zu Pandas Sache, ich werde nicht sagen, dass es eine Alternative ist, es konvertiert Spark-Datenrahmen zuerst in Pandas-Datenrahmen und führt dann Pandas-Operationen darauf durch.
Satya
1
Hallo Satya. Aktualisieren Sie einfach die Antwort, indem Sie einen .rddAnruf nach hinzufügen distinct(). In Spark 1.6.2 hat es ohne das funktioniert, aber ich habe gerade bestätigt, dass die bearbeitete Antwort auch in Spark 2.0.0 funktioniert.
Wirbel
4
Warum sollten Sie versuchen, Funken-Datenrahmenoperationen zu vermeiden, indem Sie in einen Pandas-Datenrahmen konvertieren (tut weh, wenn er gigantisch ist) oder rdd-Operationen verwenden, wenn Funken-Datenrahmen dies perfekt können? siehe unten Antwort von @Pabbati
Laurens Koppenol
@Laurens In der obigen Antwort gab es drei Lösungen, je nachdem, was das Poster wirklich wollte. In allen Fällen wollte das Poster eine Form einer Liste / eines Arrays der unterschiedlichen Werte (siehe Antwort des Posters auf die Antwort von Seufagner). Die obige dritte Lösung verwendet die Datenrahmen-API von Spark genau wie Pabbatis Antwort, gibt jedoch tatsächlich eine Liste gemäß den Anforderungen des Posters zurück.
Wirbel
1
Ja, der Fragentitel enthält das Wort "show". Das Poster stellte jedoch ausdrücklich klar, dass es nicht angemessen war, die Ergebnisse zu sehen, und wollte eine Liste. Wie oben erwähnt, siehe den Kommentar des Posters zur Antwort von Seufagner.
Wirbel
198

Dies sollte helfen, eindeutige Werte einer Spalte zu erhalten:

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

Beachten Sie, dass .collect()es keine integrierte Begrenzung für die Anzahl der zurückgegebenen Werte gibt, sodass dies möglicherweise langsam ist. Verwenden Sie .show()stattdessen oder fügen Sie .limit(20)vorher hinzu .collect(), um dies zu verwalten.

Pabbati
quelle
Dieser Code gibt Daten zurück, die nicht iterierbar sind, dh ich sehe, dass das eindeutige Datenbit im Code nicht darüber iterieren kann. Jede andere Möglichkeit, die es mir ermöglicht. Ich habe versucht, mit toPandas () in Pandas df zu konvertieren und dann das Iterable mit eindeutigen Werten zu erhalten. Es wird jedoch die Fehlermeldung "Pandas nicht gefunden"
angezeigt
6
@Abhi: Anstelle von .show () führen Sie stattdessen eine .collect () aus. Auf diese Weise erhalten Sie eine Iterierbarkeit aller unterschiedlichen Werte dieser bestimmten Spalte. Stellen Sie jedoch sicher, dass Ihr Masterknoten über genügend Speicher verfügt, um diese eindeutigen Werte zu speichern, da durch das Sammeln alle angeforderten Daten (in diesem Fall eindeutige Werte der Spalte) an den Masterknoten gesendet werden :)
Satya
1
@ Satya Ich habe Ihren Kommentar in die Antwort bearbeitet, danke
MichaelChirico
14

Sie können verwenden df.dropDuplicates(['col1','col2']), um nur unterschiedliche Zeilen basierend auf colX im Array abzurufen.

Seufagner
quelle
2
@ seufagner-yes Ich kann ein df.dropDuplictes (['col1']) ausführen, um die eindeutigen Werte zu sehen (markieren Sie SEE), aber ohne eine Erfassung (to_rdd oder pandas DF, dann df ['col']. unique ()) Ich kann die Liste der eindeutigen Werte nicht abrufen. Danke für den Vorschlag.
Satya
Der Benutzer hat nicht gefragt, wie nicht doppelte Werte angezeigt werden sollen. Er wollte nur eine Liste aller eindeutigen / unterschiedlichen Elemente erhalten, einschließlich auch doppelter Werte!
Utsav Jha
6

collect_set kann dabei helfen, eindeutige Werte aus einer bestimmten Spalte von pyspark.sql.DataFrame abzurufen df.select(F.collect_set("column").alias("column")).first()["column"]

Hari Baskar
quelle
1

Wenn Sie ALLE (Spalten-) Daten als von einem DataFrame (df) verschieden auswählen möchten, dann

df.select('*').distinct().show(10,truncate=False)

Kapil Sharma
quelle
1

du könntest es tun

distinct_column = 'somecol' 

distinct_column_vals = df.select(distinct_column).distinct().collect()
distinct_column_vals = [v[distinct_column] for v in distinct_column_vals]
Myon
quelle
0

Zusätzlich zu der dropDuplicatesOption gibt es die Methode, wie wir sie kennen :pandas drop_duplicates

drop_duplicates () ist ein Alias ​​für dropDuplicates () .

Beispiel

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

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

Drop by Teilmenge

s_df.drop_duplicates(subset = ['k']).show()

+---+---+
|  k|  v|
+---+---+
|bar|  2|
|foo|  1|
+---+---+
s_df.drop_duplicates().show()


+---+---+
|  k|  v|
+---+---+
|bar|  2|
|foo|  3|
|foo|  1|
+---+---+
ansev
quelle
0

Führen Sie dies zuerst aus

df.createOrReplaceTempView('df')

Dann renne

spark.sql("""
    SELECT distinct
        column name
    FROM
        df
    """).show()
Joseph Jacob
quelle
0

Wenn Sie die unterschiedlichen Werte einer bestimmten Spalte in Ihrem Datenrahmen anzeigen möchten, müssen Sie nur schreiben:

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

Dies würde die 100 unterschiedlichen Werte (wenn 100 Werte verfügbar sind) für die Spalte colname im df-Datenrahmen anzeigen.

Wenn Sie etwas Besonderes an den verschiedenen Werten tun möchten, können Sie die verschiedenen Werte in einem Vektor speichern

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

Hier hätte a alle unterschiedlichen Werte der Spalte colname

Nidhi
quelle