У меня есть фрейм данных pyspark, а один столбец - это список идентификаторов. Я хочу, например, получить количество строк с определенным идентификатором.
AFAIK для меня важны два типа столбцов: ArrayType
и MapType
. Я мог бы использовать тип карты, потому что проверка на членство внутри карты / dict более эффективна, чем проверка на членство в массиве.
Однако, чтобы использовать карту, мне нужно отфильтровать с помощью пользовательской udf
, а не встроенной функции (scala) array_contains
с MapType
Я могу сделать:
from pyspark.sql.types import BooleanType
from pyspark.sql.functions import udf
df = spark.createDataFrame([("a-key", {"345": True, "123": True})], ["key", "ids"])
def is_in_map(k, d):
return k in d.keys()
def map_udf(key):
return udf(lambda d: is_in_map(key, d), BooleanType())
c = df.filter(map_udf("123")(df.ids)).count()
или с ArrayType
Я могу сделать:
from pyspark.sql.functions import array_contains
df = spark.createDataFrame([("a-key", ["345", "123"])], ["key", "ids"])
c = df.filter(array_contains(df.ids, "123")).count()
Моя первая реакция - использовать MapArray
, потому что проверка на членство внутри карты (я полагаю) более эффективна.
С другой стороны, встроенная функция array_contains
выполняет код scala , и я предполагаю, что любая функция, определенная в scala, которую я вызываю, будет более эффективной, чем возвращение dict столбца в контекст Python и проверка k in d.keys()
.
Для проверки членства в этом (многозначном) столбце лучше использовать MapType
или ArrayType
pyspark.sql.types
?
Обновление
Существует метод столбца pyspark.sql.Column.getItem
, что означает, что я могу фильтровать по членству без питона udf