> 20列の「大きな」データセット(_huge_df
_)があります。列の1つはid
フィールドです(pyspark.sql.functions.monotonically_increasing_id()
で生成)。
いくつかの基準を使用して、2番目のデータフレーム(_filter_df
_)を生成します。これは、_huge_df
_から後でフィルタリングするid
値で構成されます。
現在私はこれを行うためにSQL構文を使用しています:
_filter_df.createOrReplaceTempView('filter_view')
huge_df = huge_df.where('id NOT IN (SELECT id FROM filter_view)')
_
質問1: Pythonのみを使用して、つまりTempView
を登録する必要なしに、これを行う方法はありますか?
質問2:同じことを達成するための完全に異なる方法はありますか?
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にそのような行がないことを意味します
これを行う別の方法があります-
# 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をドロップして最終結果を出しました。