Рассмотрим следующий фрейм данных,
cols = ['Id', 'col1', 'col2', 'col3']
vals = [('1A','Not his side|:|This side', 'This side', 'Not this either|:|but this'),
('1B','Keep this', 'This one|:|keep this', 'remove|:|keep that')]
dd1 = sqlContext.createDataFrame(vals, cols)
#+---+------------------------+--------------------+--------------------------+
#|Id |col1 |col2 |col3 |
#+---+------------------------+--------------------+--------------------------+
#|1A |Not his side|:|This side|This side |Not this either|:|but this|
#|1B |Keep this |This one|:|keep this|remove|:|keep that |
#+---+------------------------+--------------------+--------------------------+
Мне нужно разбить строки на |:|
и сохраните второе слово. Однако, если строка не содержит разделителя (|:|
), тогда я получаю null
, то есть:
users1 = [F.split(F.col(x), "\\|:\\|").alias(x) for x in cols]
dd1.select(*users1).show()
#+---------+---------+---------+
#| col1| col2| col3|
#+---------+---------+---------+
#|This side| null| but this|
#| null|keep this|keep that|
#+---------+---------+---------+
Результат, который я ищу, это:
+---+---------+---------+---------+
|Id |col1 |col2 |col3 |
+---+---------+---------+---------+
|1A |This side|This side|but this |
|1B |Keep this|keep this|keep that|
+---+---------+---------+---------+
Используйте, when
и в otherwise
и проверьте, содержит ли строка "|:|"
, Это можно сделать следующим образом:
cols = ['col1', 'col2', 'col3']
users1 = [F.when(F.col(x).contains("|:|"), F.split(F.col(x), "\\|:\\|")[1]).otherwise(F.col(x)).alias(x) for x in cols]
dd1.select(F.col('Id'), *users1)
Здесь cols
включают только столбцы, которые вы хотите разделить. Окончательный select
будет включать столбец Id
.
Вы можете использовать, when
и size
встроенных функций, как
users1 = [F.when(F.size(F.split(F.col(x), "\\|:\\|")) > 1, F.split(F.col(x), "\\|:\\|")[1]).otherwise(F.col(x)).alias(x) for x in cols]
dd1.select(*users1).show()
которые должны дать вам
+---+---------+---------+---------+
| Id| col1| col2| col3|
+---+---------+---------+---------+
| 1A|This side|This side| but this|
| 1B|Keep this|keep this|keep that|
+---+---------+---------+---------+
Вы можете изменить ответ, чтобы использовать функцию split
только один раз.
Я надеюсь, что ответ будет полезен и должен быть хорошим советом о том, как действовать.
Id
. Где вы выбираете это?
Выбор, который вы определили в своих вопросах, не дает результата, о котором вы говорили. Я думаю, вы забыли выбрать элемент из массива;)
users1 = [F.split(F.col(x), "\\|:\\|").alias(x) for x in cols]
dd1.select(*users1).show()
+----+--------------------+--------------------+--------------------+
| Id| col1| col2| col3|
+----+--------------------+--------------------+--------------------+
|[1A]|[Not his side, Th...| [This side]|[Not this either,...|
|[1B]| [Keep this]|[This one, keep t...| [remove, keep that]|
+----+--------------------+--------------------+--------------------+
Чтобы добиться того, чего вы хотите, вам просто нужно выбрать последний элемент массива. Вы можете использовать функцию размера для этого:
users2 = [F.col(x).getItem(F.size(F.col(x))-1).alias(x) for x in cols]
dd1.select(*users1).select(*users2).show()
+---+---------+---------+---------+
| Id| col1| col2| col3|
+---+---------+---------+---------+
| 1A|This side|This side| but this|
| 1B|Keep this|keep this|keep that|
+---+---------+---------+---------+