Pyspark: сопоставьте столбцы из двух разных фреймов данных и добавьте значение

#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")