spark基于另一个数据帧的值过滤(删除)行

时间:2017-04-19 14:00:38

标签: apache-spark pyspark apache-spark-sql pyspark-sql

我有一个很大的'数据集(huge_df),大于20列。其中一列是id字段(使用pyspark.sql.functions.monotonically_increasing_id()生成)。

使用某些条件,我会生成第二个数据帧(filter_df),其中包含id值,我希望稍后从huge_df过滤。

目前我使用SQL语法来执行此操作:

filter_df.createOrReplaceTempView('filter_view')
huge_df = huge_df.where('id NOT IN (SELECT id FROM filter_view)')

问题1: 有没有办法只使用Python,即无需注册TempView

问题2: 有没有完全不同的方法来完成同样的事情?

2 个答案:

答案 0 :(得分:6)

您可以使用JOIN

huge_df = huge_df.join(filter_df, huge_df.id == filter_df.id, "left_outer")
                 .where(filter_df.id.isNull())
                 .select([col(c) for c in huge_df.columns]

然而,这将导致昂贵的洗牌。

逻辑很简单:在id字段上保持与filter_df的连接并检查filter_df是否为null - 如果它为null,则表示filter_df中没有这样的行

答案 1 :(得分:0)

这是另一种方法 -

# Sample data
hugedf = spark.createDataFrame([[1,'a'],[2,'b'],[3,'c'],[4,'d']],schema=(['k1','v1']))
fildf = spark.createDataFrame([[1,'b'],[3,'c']],schema=(['k2','v2']))


from pyspark.sql.functions import col
hugedf\
.select('k1')\     
.subtract(fildf.select('k2'))\ 
.toDF('d1')\
.join(hugedf,col('d1')==hugedf.k1)\
.drop('d1')\
.show()

逻辑很简单,从在hugeDF中找到的id值中减去在filteredDf中找到的id值,留下不在filterDF中的ID值,

我将减去的值标记为列' d1'为了清楚起见,然后在d1值上加入hugeDF表并删除d1以得到最终结果。