#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 сработал как надо, спасибо!