2016-03-08 41 views
18

Tôi muốn lọc một Pyspark DataFrame với một IN khoản SQL-like, như trongLọc một Pyspark DataFrame với SQL giống như tại khoản

sc = SparkContext() 
sqlc = SQLContext(sc) 
df = sqlc.sql('SELECT * from my_df WHERE field1 IN a') 

nơi a là tuple (1, 2, 3). Tôi nhận được lỗi này:

java.lang.RuntimeException: [1.67] failure: ``('' expected but identifier a found

mà về cơ bản nói rằng nó đã mong một cái gì đó giống như '(1, 2, 3)' thay vì một. Vấn đề là tôi không thể viết các giá trị theo cách thủ công vì nó được trích xuất từ ​​một công việc khác.

Làm cách nào để lọc trong trường hợp này?

Trả lời

34

Chuỗi bạn chuyển đến SQLContext chuỗi được đánh giá trong phạm vi môi trường SQL. Nó không nắm bắt được sự đóng cửa. Nếu bạn muốn vượt qua một biến bạn sẽ phải làm điều đó một cách rõ ràng bằng chuỗi định dạng:

df = sc.parallelize([(1, "foo"), (2, "x"), (3, "bar")]).toDF(("k", "v")) 
df.registerTempTable("df") 
sqlContext.sql("SELECT * FROM df WHERE v IN {0}".format(("foo", "bar"))).count() 
## 2 

Rõ ràng đây không phải là một cái gì đó bạn sẽ sử dụng trong một "thực sự" môi trường SQL do cân nhắc an ninh nhưng nó không nên vấn đề ở đây.

Trong thực tế DataFrame DSL là một sự lựa chọn hơn khi bạn muốn tạo các truy vấn động:

from pyspark.sql.functions import col 

df.where(col("v").isin({"foo", "bar"})).count() 
## 2 

Nó rất dễ dàng để xây dựng và soạn và xử lý tất cả các chi tiết của HiveQL/Spark SQL cho bạn.

+0

Đối với phương pháp thứ hai, bạn có thể đạt được như vậy bằng cách làm df.where (df.v.isin ({"foo", "bar"})). count() –

+3

Bạn có thể, nhưng cá nhân tôi không thích cách tiếp cận này. Với 'col', tôi có thể dễ dàng phân tách biểu thức SQL và đối tượng' DataFrame' cụ thể. Vì vậy, bạn có thể ví dụ như giữ một từ điển của các biểu thức hữu ích và chỉ cần chọn chúng khi bạn cần. Với đối tượng DF rõ ràng, bạn sẽ phải đặt nó bên trong một hàm và nó không soạn thảo tốt như vậy. – zero323

12

Nhắc lại những gì @ zero323 đã đề cập ở trên: chúng ta có thể làm điều tương tự sử dụng một danh sách cũng (không chỉ set) như dưới đây

from pyspark.sql.functions import col 

df.where(col("v").isin(["foo", "bar"])).count() 
Các vấn đề liên quan