Pyspark одновременно удаляет из 2 списков в датафрейме - PullRequest
1 голос
/ 10 апреля 2020

У меня проблема с огромным набором данных, и я пытаюсь удалить тот же индексированный элемент из 2 списков.

Позвольте мне привести пример.

Представьте себе поиск Google - список из 12 URL-адресов со страницы. Первый - это реклама, а последний - второй, а седьмой - ссылка на изображение. Теперь я хочу только организмов c link с.

Типы могут быть расположены в списке случайным образом. Я проверял array_remove, что довольно приятно, но он может удалить только определенный элемент c из 1 списка, и я не достаточно продвинут, чтобы понять, как сделать это одновременно для 2 списков. К сожалению, набор данных действительно большой, и я боюсь, что posexplode не подходит для меня здесь.

Имейте в виду, что это столбец списков , а не столбец отдельных элементов.

Я ищу что-то вроде

if "adlink" or "picture" in typelist:
   remove it from typelist and remove same indexed item from urls list
  urls  |  type 
-----------------
[url1,  | [adlink, 
 url2,  |  picture,
 url3,  |  link,
 url4,  |  link,
 url5,  |  link, 
 url6,  |  link,
 url7,  |  picture,
 url8,  |  link,
 url9,  |  link,
 url10, |  link,
 url11, |  link,
 url12] |  adlink]

Желаемый вывод:

  urls  |  type 
-----------------
[url3,  | [link,
 url4,  |  link,
 url5,  |  link, 
 url6,  |  link,
 url8,  |  link,
 url9,  |  link,
 url10, |  link,
 url11] |  link]

1 Ответ

1 голос
/ 10 апреля 2020
df.show()#your dataframe
+---------------------------------------------------------------------------+----------------------------------------------------------------------------------+
|urls                                                                       |type                                                                              |
+---------------------------------------------------------------------------+----------------------------------------------------------------------------------+
|[url1, url2, url3, url4, url5, url6, url7, url8, url9, url10, url11, url12]|[adlink, picture, link, link, link, link, picture, link, link, link, link, adlink]|
+---------------------------------------------------------------------------+----------------------------------------------------------------------------------+ 

Вы можете использовать higher order functions, поскольку у вас есть spark2.4 (я могу сказать, потому что вы использовали array_remove). Сначала вы можете застегнуть массивы вместе, используя arrays_zip, а затем использовать filter на zipped array(type_urls) to Отфильтруйте где угодно type is 'adlink' and 'picture', затем выберите нужные столбцы из сжатого столбца, используя columname.arrayname.

Filter (функция более высокого порядка), в основном позволяет применять фильтр к данным более высокого порядка без необходимости их разнесения (как вы упомянули posexplode ) . Функции высшего порядка

arrays_zip Возвращает объединенный массив структур, в котором N-тая структура содержит все N-тые значения входных массивов. arrays_zip Документы API Pyspark

from pyspark.sql import functions as F
df.withColumn("type_urls", F.arrays_zip(F.col("urls"),F.col("type"))).select("type_urls")\
  .withColumn("urls1", F.expr("""filter(type_urls, x-> x.type!='adlink' and x.type!='picture')"""))\
  .select(F.col("urls1.urls"), F.col("urls1.type")).show(truncate=False)

+--------------------------------------------------+------------------------------------------------+
|urls                                              |type                                            |
+--------------------------------------------------+------------------------------------------------+
|[url3, url4, url5, url6, url8, url9, url10, url11]|[link, link, link, link, link, link, link, link]|
+--------------------------------------------------+------------------------------------------------+
...