簡體   English   中英

使用類似 SQL 的 IN 子句過濾 Pyspark DataFrame

[英]Filtering a Pyspark DataFrame with SQL-like IN clause

我想用類似 SQL 的IN子句過濾 Pyspark DataFrame,如

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

其中a是元組(1, 2, 3) 我收到此錯誤:

java.lang.RuntimeException: [1.67] 失敗:``('' 預期但找到標識符

這基本上是說它期待類似“(1, 2, 3)”的東西而不是a。 問題是我無法在 a 中手動寫入值,因為它是從另一個作業中提取的。

在這種情況下我將如何過濾?

您傳遞給它在 SQL 環境范圍內評估的SQLContext字符串。 它不捕獲閉包。 如果要傳遞變量,則必須使用字符串格式顯式執行此操作:

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 

顯然,出於安全考慮,這不是您將在“真實”SQL 環境中使用的東西,但在這里應該無關緊要。

實際上,當您想要創建動態查詢時, DataFrame DSL 是一個更好的選擇:

from pyspark.sql.functions import col

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

很容易為您構建和組合並處理 HiveQL/Spark SQL 的所有細節。

重申@zero323 上面提到的內容:我們也可以使用列表(不僅是set來做同樣的事情,如下所示

from pyspark.sql.functions import col

df.where(col("v").isin(["foo", "bar"])).count()

只是一點點添加/更新:

choice_list = ["foo", "bar", "jack", "joan"]

如果你想過濾你的數據框“df”,這樣你就想根據列“v”保留行,只取choice_list中的值,然后

from pyspark.sql.functions import col

df_filtered = df.where( ( col("v").isin (choice_list) ) )

您也可以對整數列執行此操作:

df_filtered = df.filter("field1 in (1,2,3)")

或者這對於字符串列:

df_filtered = df.filter("field1 in ('a','b','c')")

對我有用的略有不同的方法是使用自定義過濾器功能進行過濾。

def filter_func(a):
"""wrapper function to pass a in udf"""
    def filter_func_(col):
    """filtering function"""
        if col in a.value:
            return True

    return False

return udf(filter_func_, BooleanType())

# Broadcasting allows to pass large variables efficiently
a = sc.broadcast((1, 2, 3))
df = my_df.filter(filter_func(a)(col('field1'))) \
from pyspark.sql import SparkSession
import pandas as pd
spark=SparkSession.builder.appName('Practise').getOrCreate()
df_pyspark=spark.read.csv('datasets/myData.csv',header=True,inferSchema=True)
df_spark.createOrReplaceTempView("df") # we need to create a Temp table first
spark.sql("SELECT * FROM df where Departments in ('IOT','Big Data') order by Departments").show()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM