2016-05-12 3 views
0

Я имею следующие dataframe (значения внутри массива являются строками):Спарк Dataframes: добавление списка в новом столбце (питон)

+--------------------+--------------------+ 
|    col1|    col2| 
+--------------------+--------------------+ 
| [value1, value2]|  [value3,value4]| 
|   [value5]|   [value6]| 
+--------------------+--------------------+ 

Как я могу создать новый столбец с новым массивом, включая все значения обоих

+--------------------+--------------------+------------------------------+ 
|    col1|    col2|       new | 
+--------------------+--------------------+------------------------------+ 
| [value1, value2]|  [value3,value4]|[value1, value2,value3,value4]| 
|   [value5]|   [value6]|    [value5,value6]| 
+--------------------+--------------------+------------------------------+ 

Я попытался следующие:

def add_function(col1,col2): 
    return col1+col2 

udf_add = udf(add_function,ArrayType(StringType())) 
dftrial.withColumn("new",udf_add("col1","col2")).show(2) 

Это действительно делает задачу по желанию. Но я не понимаю, почему, когда я изменить add_function к: значение

def add_function(col1,col2): 
    return col1.extend(col2) 

возвращает null. Зачем?

И мой главный вопрос: есть ли другой способ реализовать эту задачу? Любая уже реализованная функция? Я нашел concat, но кажется, что он работает только для строк.

ответ

1

Почему бы и нет? Используя подсказки list.extend типа Python является:

list.extend(iterable) -> None 

Таким образом, вы получите именно то, что возвращается из extend. Если вы хотите вернуть коллекцию изменений, вы должны действительно вернуть col1, но, пожалуйста, не делайте этого, потому что здесь есть худшая часть.

Вы должны Никогда изменить данные на месте при работе с искровым зажиганием. Хотя в этом конкретном сценарии вы в безопасности, это может иметь непредсказуемые последствия. Вы можете найти возможный пример в моем ответе Will there be any scenario, where Spark RDD's fail to satisfy immutability.?. Хотя PySpark относительно изолирован от подобных действий, это всего лишь деталь реализации, а не то, от чего вы можете вообще зависеть.

+0

Спасибо за ваш ответ. Можете ли вы пояснить, чего я никогда не должен делать? Потому что я не понял его точно и, похоже, это важная информация, которую мне не хватает. –

+1

'list.extend' изменяет (мутирует) существующий' list'. Не делайте этого с вашими данными. Всегда возвращайте новый объект, если явно не разрешено делать иначе (см. «RDD.fold», «RDD.aggregate» и т. Д.). – zero323

0

Я согласен с @ zero323. Я просто хотел добавить преобразование, необходимое для получения решения в новом фреймворке данных.

val updatedDataframe = initialDataframe.map { 
    case Row(col1: Seq[String], col2: Seq[String]) => (col1, col2, col1.union(col2)) 
    }.toDF("col1", "col2", "col3") 
Смежные вопросы