J'ai un "gros" jeu de données (huge_df
) avec plus de 20 colonnes. L'une des colonnes est un champ id
(généré avec pyspark.sql.functions.monotonically_increasing_id()
).
En utilisant certains critères, je génère une deuxième image (filter_df
), composée de valeurs id
que je souhaite filtrer ultérieurement à partir de huge_df
.
Actuellement, j'utilise la syntaxe SQL pour faire ceci:
filter_df.createOrReplaceTempView('filter_view')
huge_df = huge_df.where('id NOT IN (SELECT id FROM filter_view)')
Question 1: Y at-il un moyen de faire cela en utilisant uniquement Python, c’est-à-dire sans avoir besoin d’enregistrer la variable TempView
?
Question 2: Existe-t-il une méthode complètement différente pour accomplir la même chose?
Vous pouvez utiliser 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]
Cependant, cela entraînera un remaniement coûteux.
La logique est simple: joignez-vous à gauche à filter_df sur les champs id et vérifiez si filter_df est null - si c'est null, cela signifie qu'il n'y a pas de telle ligne dans filter_df
Voici une autre façon de le faire-
# 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()
la logique est simple, soustrayez les valeurs d'ID trouvées dans filterDf des valeurs d'ID trouvées dans hugeDF en laissant des valeurs d'ID qui ne figurent pas dans filterDF,
J'ai marqué les valeurs soustraites dans la colonne 'd1' juste pour des raisons de clarté, puis je me suis joint à une table énormeDF sur les valeurs de d1 et j'ai abandonné d1 pour obtenir le résultat final.