pokaż różne wartości kolumn w pyspark dataframe: python

85

Proszę zasugerować alternatywną ramkę danych pyspark dla Pand df['col'].unique().

Chcę wymienić wszystkie unikalne wartości w kolumnie dataframe pyspark.

Nie sposób typu SQL (szablon rejestru, a następnie zapytanie SQL dla różnych wartości).

Również nie potrzebuję groupby->countDistinct, zamiast tego chcę sprawdzić różne WARTOŚCI w tej kolumnie.

Satya
źródło

Odpowiedzi:

86

Załóżmy, że pracujemy z następującą reprezentacją danych (dwie kolumny ki v, jeśli kzawiera trzy wpisy, dwie unikalne):

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

Z ramką danych Pandas:

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

Zwraca to ndarray, tjarray(['foo', 'bar'], dtype=object)

Poprosiłeś o „alternatywną ramkę danych pyspark dla pandas df ['col']. Unique ()”. Teraz, biorąc pod uwagę następującą ramkę danych Spark:

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

Jeśli chcesz uzyskać ten sam wynik ze Sparka, tj. ndarrayUżyj toPandas():

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

Alternatywnie, jeśli nie potrzebujesz ndarraykonkretnego i po prostu chcesz listę unikalnych wartości kolumny k:

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

Na koniec możesz również użyć rozumienia listy w następujący sposób:

[i.k for i in s_df.select('k').distinct().collect()]
wiry
źródło
1
Cześć Eddies, ostatnia linia kodu odrębna (). Map () nie działała dla mnie. Błąd: AttributeError: obiekt „DataFrame” nie ma atrybutu „map”. Jestem na iskrze 2.0. I jeśli chodzi o Pandy, nie powiem, że jest to alternatywa, najpierw konwertuje iskierkę Dataframe na pandas Dataframe, a następnie wykonuje na niej operacje na pandach.
Satya
1
Cześć Satya. Właśnie zaktualizowałem odpowiedź, dodając .rddpołączenie po distinct(). Działało bez tego w Spark 1.6.2, ale właśnie potwierdziłem, że edytowana odpowiedź działa również w Spark 2.0.0.
eddies
4
Po co próbować unikać iskierkowych operacji dataframe, konwertując na pandas dataframe (boli, jeśli jest gigantyczna) lub wykorzystując operacje rdd, skoro spark dataframe jest do tego doskonale zdolna? zobacz poniżej odpowiedź @Pabbati
Laurens Koppenol
@Laurens W powyższej odpowiedzi były trzy rozwiązania, w zależności od tego, czego naprawdę chciał plakat. We wszystkich przypadkach plakat chciał mieć jakąś formę listy / tablicy różnych wartości (por. Odpowiedź postera na odpowiedź seufagnera). Trzecie rozwiązanie powyżej wykorzystuje interfejs API Dataframe Sparka tak samo, jak odpowiedź Pabbati, ale w rzeczywistości zwraca listę, zgodnie z wymaganiami nadawcy.
eddies
1
Tak, tytuł pytania zawiera słowo „pokaż”. Ale plakat wyraźnie wyjaśniał, że WIDZENIE wyników nie jest adekwatne i wymaga listy. Jak wspomniano powyżej, zobacz komentarz autora do odpowiedzi Seufagner.
eddies
200

Powinno to pomóc w uzyskaniu różnych wartości kolumny:

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

Pamiętaj, że .collect()nie ma żadnego wbudowanego limitu liczby zwracanych wartości, więc może to być powolne - użyj .show()zamiast tego lub dodaj .limit(20)wcześniej, .collect()aby to zarządzać.

Pabbati
źródło
ten kod zwraca dane, które nie są iterowalne, tj. widzę, że oddzielny bit danych nie jest w stanie iterować po nim w kodzie. Każdy inny sposób, który mi na to pozwala. Próbowałem użyć toPandas (), aby przekonwertować go na Pandas df, a następnie uzyskać iterowalność z unikalnymi wartościami. Jednak napotkanie komunikatu o błędzie „Nie znaleziono Pandy”
Abhi
6
@Abhi: zamiast .show () wykonaj zamiast tego .collect (), w ten sposób otrzymasz iterowalność wszystkich odrębnych wartości tej konkretnej kolumny. Ale upewnij się, że węzeł nadrzędny ma wystarczającej ilości pamięci do przechowywania trzymać tych unikatowych wartości, ponieważ zbierać pchnie wszystkie wymagane dane (w tym przypadku unikalne wartości kolumny) do głównego węzła :)
Satya
1
@Satya Zmieniłem twój komentarz w odpowiedzi, dzięki
MichaelChirico
14

Możesz użyć, df.dropDuplicates(['col1','col2'])aby uzyskać tylko różne wiersze na podstawie colX w tablicy.

seufagner
źródło
2
@ seufagner-yes Mogę zrobić df.dropDuplictes (['col1']), aby zobaczyć (zaznacz SEE) unikalne wartości, ale bez zbierania (to_rdd lub do pandy DF, a następnie df ['col']. unique ()) , Nie mogę uzyskać listy unikalnych wartości. Dzięki za sugestię.
Satya
Użytkownik nie pytał, jak wyświetlić wartości, które nie są zduplikowane. Po prostu chciał uzyskać listę wszystkich unikalnych / odrębnych elementów, która obejmuje również duplikaty!
Utsav Jha
6

collect_set może pomóc w uzyskaniu unikalnych wartości z danej kolumny pyspark.sql.DataFrame df.select(F.collect_set("column").alias("column")).first()["column"]

Hari Baskar
źródło
1

Jeśli chcesz wybrać WSZYSTKIE (kolumny) dane jako odrębne z DataFrame (df), to

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

Kapil Sharma
źródło
1

mógłbyś

distinct_column = 'somecol' 

distinct_column_vals = df.select(distinct_column).distinct().collect()
distinct_column_vals = [v[distinct_column] for v in distinct_column_vals]
mion
źródło
0

Oprócz dropDuplicatesopcji istnieje metoda nazwana tak, jak ją znamy w :pandas drop_duplicates

drop_duplicates () jest aliasem dla dropDuplicates () .

Przykład

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|
+---+---+

Upuść według podzbioru

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
źródło
0

Uruchom to najpierw

df.createOrReplaceTempView('df')

Następnie uruchomić

spark.sql("""
    SELECT distinct
        column name
    FROM
        df
    """).show()
Joseph Jacob
źródło
0

Jeśli chcesz zobaczyć różne wartości określonej kolumny w swojej ramce danych, wystarczy napisać -

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

Spowoduje to wyświetlenie 100 odrębnych wartości (jeśli dostępnych jest 100 wartości) dla kolumny Colname w ramce danych df.

Jeśli chcesz zrobić coś wymyślnego na odrębnych wartościach, możesz zapisać różne wartości w wektorze

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

W tym przypadku a miałoby wszystkie różne wartości kolumny kolumna

Nidhi
źródło