Поскольку вы используете Spark версии 2.3.2, transform
Вам недоступно. Таким образом, как объясняется в сообщении , в общем случае лучше всего использовать udf
.
Однако в этом конкретном случае вы можете избежать udf
, используя некоторые хакерские замены регулярных выражений.
from pyspark.sql.functions import col, concat_ws, regexp_replace, split, trim
df.withColumn(
"newcolname",
regexp_replace(concat_ws(",", col("colname")), "((?<=_)[^_,]+(?=_))", " $1 ")
).withColumn(
"newcolname",
regexp_replace(col("newcolname"), "(_[^_ ]+_)", "")
).withColumn(
"newcolname",
regexp_replace(col("newcolname"), "([^_ ]+_)", "")
).withColumn(
"newcolname",
regexp_replace(col("newcolname"), "_([^_ ]+)", "")
).withColumn(
"newcolname",
split(trim(col("newcolname")), "\s+")
).show(truncate=False)
#+------------------------------------+------------+
#|colname |newcolname |
#+------------------------------------+------------+
#|[foo_XX_foo, bar_YY_bar] |[XX, YY] |
#|[qwe_ZZ_rty, asd_AA_fgh, zxc_BB_vbn]|[ZZ, AA, BB]|
#+------------------------------------+------------+
Объяснение
Сначала мы берем столбец ArrayType(StringType())
и объединяем элементы вместе, чтобы сформировать одну строку. Я использовал запятую в качестве разделителя, которая работает только в том случае, если запятая не появляется в ваших данных.
Далее мы выполняем серию regexp_replace
вызовов.
Первый шаблон ((?<=_)[^_,]+(?=_))
идентифицирует содержимое, которое вы действительно хотите извлечь: текст, заключенный в квадратные скобки с символом подчеркивания. Затем соответствующие группы заменяются группой соответствия, окруженной пробелами " $1 "
. Как и раньше с разделителем-запятой, это предполагает, что в ваших данных нет пробелов.
Например:
df.select(
regexp_replace(
concat_ws(",", col("colname")),
"((?<=_)[^_,]+(?=_))",
" $1 "
).alias("pattern1")
).show(truncate=False)
#+--------------------------------------+
#|pattern1 |
#+--------------------------------------+
#|foo_ XX _foo,bar_ YY _bar |
#|qwe_ ZZ _rty,asd_ AA _fgh,zxc_ BB _vbn|
#+--------------------------------------+
Следующие 3 вызова regexp_replace
выборочно удаляют ненужные части этой строки.
Наконец, в конце остается только желаемый контент. Строка обрезается для удаления конечных/начальных пробелов и разбивается на пробелы, чтобы получить окончательный результат.
person
pault
schedule
25.10.2019
transform
доступен только в версии 2.4+. Ваш лучший вариант, вероятно,udf
, хотя есть хакерский способ с использованиемconcat_ws
,regexp_extract
иsplit
- person pault   schedule 25.10.2019