Как я могу запросить, где столбец существует в другом столбце? - PullRequest
1 голос
/ 06 января 2020

У меня есть фрейм данных, который содержит столбец с именами страниц и другой столбец, который содержит Json со списком страниц. Я хотел бы проверить, отображается ли имя страницы в списке страниц, и отфильтровать его, если его нет.

Как я могу это сделать?

df например:

+---------+--------------------------------+
|page name|page_list                       |
+---------+--------------------------------+
|home     |{page_list:['home','something']}|
|about    |{page_list:['something']}       |
+---------+--------------------------------+

Ответы [ 3 ]

1 голос
/ 06 января 2020

Предполагая, что ваша схема DataFrame похожа на следующую (здесь столбец page_list представляет собой строку):

df.printSchema()
#root
# |-- page_name: string (nullable = true)
# |-- page_list: string (nullable = true)

Вы можете использовать from_json, чтобы получить page_list как массив строк. Затем используйте array_contains, чтобы проверить, есть ли page_name в этом списке.

Хитрость заключается в том, что вам придется использовать expr до передачи значения столбца в качестве параметра от до array_contains.

from pyspark.sql.types import StructType, StructField, ArrayType, StringType
from pyspark.sql.functions import expr, from_json

df.withColumn(
    "flag",
    from_json(
        "page_list", 
        schema=StructType([StructField("page_list", ArrayType(StringType()))])
    )["page_list"]
).withColumn(
    "flag",
    expr("array_contains(flag, page_name)")
).show(truncate=False)
#+---------+----------------------------------+-----+
#|page_name|page_list                         |flag |
#+---------+----------------------------------+-----+
#|home     |{"page_list":["home","something"]}|true |
#|about    |{"page_list":["something"]}       |false|
#+---------+----------------------------------+-----+
0 голосов
/ 06 января 2020

Если столбец page_list имеет тип string, вы можете просто использовать функцию contains следующим образом:

quoted_page_name = concat(lit("'"), col("page_name"), lit("'"))    
df.withColumn("flag", col("page_list").contains(quoted_page_name)).show()

Дает:

+---------+----------------------------------+-----+
|page_name|page_list                         |flag |
+---------+----------------------------------+-----+
|home     |{page_list: ['home', 'something']}|true |
|about    |{page_list: ['something']}        |false|
+---------+----------------------------------+-----+
0 голосов
/ 06 января 2020

Вот способ сделать:

df2 = (df
      .rdd
      .map(lambda x: (x.page_name, x.page_list, x.page_name in x.page_list['page_list']))
      .toDF(["page_name", "page_list", "flag"])

df2.show()

+---------+--------------------+-----+
|page_name|           page_list| flag|
+---------+--------------------+-----+
|     home|[page_list -> [ho...| true|
|    about|[page_list -> [so...|false|
+---------+--------------------+-----+
...