Как исключить элементы, содержащиеся в другом столбце — фрейм данных Pyspark

#python #dataframe #pyspark

#питон #фрейм данных #пыспарк

Вопрос:

Представьте, что у вас есть фрейм данных pyspark df с тремя столбцами: A, B, C . Я хочу взять строки во фрейме данных, где значение B не существует в C.

Пример:

 A B C a 1 2 b 2 4 c 3 6 d 4 8   

бы вернулся

 A B C a 1 2 c 3 6  

Что я пытался

 df.filter(~df.B.isin(df.C))  

Я также попытался внести значения B в список, но это занимает значительное количество времени.

Комментарии:

1. @Крис лок не работает в писпарке, вы думаете о пандах

Ответ №1:

Проблема в том, как вы используете isin . К лучшему или худшему, isin на самом деле не может обрабатывать другой Column объект pyspark в качестве входных данных, ему нужна фактическая коллекция. Поэтому одна вещь, которую вы могли бы сделать, — это преобразовать свою колонку в список :

 col_values = df.select("C").rdd.flatMap(lambda x: x).collect() df.filter(~df.B.isin(col_values))  

Однако с точки зрения производительности это, очевидно, не идеально, поскольку ваш главный узел теперь отвечает за управление всем содержимым одного столбца, который вы только что загрузили в память. Вы можете использовать левое антисоединение для получения нужного вам результата без необходимости преобразовывать что-либо в список и потери эффективности распределенных вычислений spark :

 df0 = df[["C"]].withColumnRenamed("C", "B") df.join(df0, "B", "leftanti").show()  

Спасибо Эмме в комментариях за ее вклад.

Комментарии:

1. должно ли это быть left_anti вместо leftsemi этого ?

2. И вот так просто вы все поняли 😀 Обновляю свой ответ сейчас.

3. left_anti сработал как надо, спасибо!