hiển thị các giá trị cột riêng biệt trong khung dữ liệu pyspark: python


82

Vui lòng đề xuất thay thế khung dữ liệu pyspark cho Gấu trúc df['col'].unique().

Tôi muốn liệt kê tất cả các giá trị duy nhất trong cột khung dữ liệu pyspark.

Không phải kiểu SQL (đăng ký phương thức truy vấn sau đó truy vấn SQL cho các giá trị riêng biệt).

Ngoài ra, tôi không cần groupby->countDistinct, thay vào đó tôi muốn kiểm tra các GIÁ TRỊ riêng biệt trong cột đó.

Câu trả lời:


84

Giả sử chúng ta đang làm việc với biểu diễn dữ liệu sau (hai cột kv, trong đó kchứa ba mục nhập, hai mục duy nhất:

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

Với khung dữ liệu Pandas:

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

Điều này trả về một ndarray, tức làarray(['foo', 'bar'], dtype=object)

Bạn đã yêu cầu "thay thế khung dữ liệu pyspark cho gấu trúc df ['col']. Unique ()". Bây giờ, với khung dữ liệu Spark sau:

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

Nếu bạn muốn kết quả tương tự từ Spark, tức là an ndarray, hãy sử dụng toPandas():

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

Ngoài ra, nếu bạn không cần ndarraycụ thể và chỉ muốn có danh sách các giá trị duy nhất của cột k:

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

Cuối cùng, bạn cũng có thể sử dụng cách hiểu danh sách như sau:

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

1
Xin chào eddies, dòng mã cuối cùng khác biệt (). Map () không phù hợp với tôi. Lỗi: AttributeError: Đối tượng 'DataFrame' không có thuộc tính 'bản đồ'. Tôi đang sử dụng spark 2.0. Và điều toPandas, tôi sẽ không nói nó là một giải pháp thay thế, nó chuyển đổi khung dữ liệu spark thành khung dữ liệu gấu trúc trước tiên sau đó thực hiện thao tác với gấu trúc trên đó.
Satya

1
Chào satya. Chỉ cần cập nhật câu trả lời bằng cách thêm một .rddcuộc gọi sau distinct(). Nó hoạt động mà không có trong Spark 1.6.2, nhưng tôi chỉ xác nhận rằng câu trả lời đã chỉnh sửa cũng hoạt động trong Spark 2.0.0.
xoáy

4
Tại sao lại cố gắng tránh các hoạt động của khung dữ liệu spark bằng cách chuyển đổi sang khung dữ liệu gấu trúc (rất khó nếu nó quá lớn) hoặc sử dụng các hoạt động rdd khi khung dữ liệu spark hoàn toàn có khả năng thực hiện điều này? xem câu trả lời bên dưới của @Pabbati
Laurens Koppenol

@Laurens Có ba giải pháp trong câu trả lời ở trên, tùy thuộc vào những gì người đăng thực sự muốn. Trong mọi trường hợp, người đăng muốn một số dạng danh sách / mảng các giá trị riêng biệt (phản hồi của người đăng đối với câu trả lời của seufagner). Giải pháp thứ ba ở trên sử dụng api khung dữ liệu của Spark giống như câu trả lời của Pabbati nhưng thực sự trả về một danh sách, theo yêu cầu của người đăng.
xoáy vào

1
Có, tiêu đề câu hỏi bao gồm từ "hiển thị". Nhưng người đăng tải đã nói rõ rằng việc XEM kết quả là không đầy đủ và muốn có một danh sách. Như đã đề cập ở trên, hãy xem bình luận của người đăng đối với câu trả lời của seufagner.
eddies

198

Điều này sẽ giúp nhận được các giá trị riêng biệt của một cột:

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

Lưu ý rằng .collect()không có bất kỳ giới hạn tích hợp nào về số lượng giá trị có thể trả về, vì vậy điều này có thể chậm - hãy sử dụng .show()thay thế hoặc thêm .limit(20)trước .collect()để quản lý điều này.


mã này trả về dữ liệu không thể lặp lại, tức là tôi thấy bit dữ liệu riêng biệt không thể lặp lại nó trong mã. Bất kỳ cách nào khác cho phép tôi làm điều đó. Tôi đã thử sử dụng toPandas () để chuyển đổi trong đó thành Pandas df và sau đó nhận được tệp có thể lặp lại với các giá trị duy nhất. Tuy nhiên, gặp phải thông báo lỗi '' Pandas not found '
Abhi

6
@Abhi: thay cho .show () thay vào đó là .collect (), theo cách đó bạn sẽ nhận được một giá trị có thể lặp lại của tất cả các giá trị riêng biệt của cột cụ thể đó. Nhưng hãy chắc chắn rằng nút chính của bạn có đủ bộ nhớ để giữ chân những giá trị độc đáo, vì thu thập sẽ đẩy tất cả các dữ liệu được yêu cầu (trong trường hợp này giá trị duy nhất của cột) để làm chủ Node :)
Satya

1
@Satya Tôi đã chỉnh sửa bình luận của bạn thành câu trả lời, cảm ơn
MichaelChirico

14

Bạn có thể sử dụng df.dropDuplicates(['col1','col2'])để chỉ lấy các hàng riêng biệt dựa trên colX trong mảng.


2
@ seufagner-yes Tôi có thể thực hiện df.dropDuplictes (['col1']) để xem (đánh dấu XEM) các giá trị duy nhất, nhưng không có tập hợp (to_rdd hoặc gấu trúc DF thì df ['col']. unique ()) , Tôi không thể lấy danh sách giá trị duy nhất. Cảm ơn đã gợi ý.
Satya

Người dùng không hỏi làm thế nào để hiển thị các giá trị không trùng lặp .. Anh ta chỉ muốn nhận danh sách tất cả các mục duy nhất / riêng biệt, bao gồm cả các mục trùng lặp!
Utsav Jha

6

collect_set có thể giúp lấy các giá trị duy nhất từ ​​một cột nhất định của pyspark.sql.DataFrame df.select(F.collect_set("column").alias("column")).first()["column"]


1

Nếu bạn muốn chọn TẤT CẢ (cột) dữ liệu riêng biệt từ DataFrame (df), thì

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


1

bạn có thể làm

distinct_column = 'somecol' 

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

0

Ngoài dropDuplicatestùy chọn, có phương thức được đặt tên như chúng ta biết trong :pandas drop_duplicates

drop_duplicates () là một bí danh cho dropDuplicates () .

Thí dụ

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

Từng tập hợp con

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

0

Chạy cái này trước

df.createOrReplaceTempView('df')

Sau đó chạy

spark.sql("""
    SELECT distinct
        column name
    FROM
        df
    """).show()

0

Nếu bạn muốn xem các giá trị riêng biệt của một cột cụ thể trong khung dữ liệu của mình, bạn chỉ cần viết:

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

Điều này sẽ hiển thị 100 giá trị riêng biệt (nếu 100 giá trị có sẵn) cho cột tên miền trong khung dữ liệu df.

Nếu bạn muốn làm điều gì đó lạ mắt trên các giá trị riêng biệt, bạn có thể lưu các giá trị riêng biệt trong một vectơ

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

Ở đây, a sẽ có tất cả các giá trị riêng biệt của tên cột

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.