#python #dataframe #pyspark #jupyter-lab
Вопрос:
Я пытаюсь сравнить значения двух столбцов, которые существуют в разных кадрах данных, чтобы создать новый кадр данных на основе соответствия критериям:
df1=
| id | | -- | | 1 | | 2 | | 3 | | 4 | | 5 |
df2 =
| id | | -- | | 2 | | 5 | | 1 |
Итак, я хочу добавить » x «в поле is_used, когда поле df2 существует в поле df1, иначе добавьте «NA», чтобы создать результирующий кадр данных, подобный этому:
df3 =
| id | is_used | | -- | ------- | | 1 | X | | 2 | X | | 3 | NA | | 4 | NA | | 5 | X |
Я пробовал этот способ, но критерии выбора ставят «X» во всех столбцах:
df3 = df3.withColumn('is_used', F.when( condition = (F.arrays_overlap(F.array(df1.id), F.array(df2.id))) == False, value = 'NA' ).otherwise('X'))
Я был бы признателен за любую помощь
Ответ №1:
Попробуйте присоединиться fullouter
:
df3 = ( df1.join(df2.alias("df2"), df1.id == df2.id, "fullouter") .withColumn( "is_used", F.when(F.col("df2.id").isNotNull(), F.lit("X")).otherwise(F.lit("NA")), ) .drop(F.col("df2.id")) .orderBy(F.col("id")) )
Результат:
--- ------- |id |is_used| --- ------- |1 |X | |2 |X | |3 |NA | |4 |NA | |5 |X | --- -------
Комментарии:
1. Привет, я попробовал ваш код, но я не могу решить свою проблему, в любом случае, большое вам спасибо. Реши мою проблему так же, как и твою
2. @Mik3lmao, пожалуйста.
Ответ №2:
Попробуйте следующий код, он даст вам аналогичный результат, и вы сможете внести остальные изменения:
df3 = df1.alias("df1"). join(df2.alias("df2"), (df1.id==df2.id), how='left'). withColumn('is_true', F.when(df1.id == df2.id,F.lit("X")).otherwise(F.lit("NA"))). select("df1.*","is_true") df3.show()
Комментарии:
1. Я попробовал ваш код, он работает, но у меня все еще та же проблема, столбец игнорирует критерии соответствия и добавляет крестик во все строки. Я проверил, что это правильно, но нет, мой df1 содержит 261 запись, мой df2 содержит 152, поэтому я должен видеть только 152 «X», но я вижу, что весь столбец заполнен «X» 🙁
Ответ №3:
Прежде всего, я хочу поблагодарить людей, которые внесли свой код, было очень полезно понять, что происходит.
Проблема заключалась в том, что при попытке сделать df1.id == df2.id Искра выводила оба столбца как один, потому что у них обоих было одно и то же имя, поэтому результат всех итераций всегда будет верным.
Просто переименуйте поля, которые я хотел сравнить, и это полностью сработало для меня.
Вот код:
df2 = df2.withColumnRenamed("id", "id1") df3 = df1.alias("df1").join(df2.alias("df2"), (df1.id == df2.id1), "left") df3 = df3.withColumn("is_used", F.when(df1.id == df2.id1), "X").otherwise("NA") df3 = df3.drop("id1")