Как обновить значение в массиве структур в фрейме данных в pyspark?

#apache-spark #pyspark #apache-spark-sql

Вопрос:

У меня есть следующая схема:

 gt;gt;gt; df.printSchema() root ... SNIP ...  |-- foo: array (nullable = true)  | |-- element: struct (containsNull = true) ... SNIP ...  | | |-- value: double (nullable = true)  | | |-- value2: double (nullable = true)  

В этом случае у меня есть только одна строка в фрейме данных и в массиве foo :

 gt;gt;gt; df.count() 1 gt;gt;gt; df.select(explode('foo').alias("fooColumn")).count() 1  

value равно нулю:

 gt;gt;gt; df.select(explode('foo').alias("fooColumn")).select('fooColumn.value','fooColumn.value2').show()  ----- ------  |value|value2|  ----- ------  | null| null|  ----- ------   

Я хочу отредактировать value и создать новый фрейм данных. Я могу взорваться foo и установить value :

 gt;gt;gt; fooUpdated = df.select(explode("foo").alias("fooColumn")).select("fooColumn.*").withColumn('value', lit(10)).select('value').show()  -----  |value|  -----  | 10|  -----   

Как свернуть этот fooUpdated фрейм данных, чтобы вернуть его в виде массива с элементом структуры, или есть способ сделать это без взрыва foo ?

В конце концов, я хочу, чтобы у меня было следующее:

 gt;gt;gt; dfUpdated.select(explode('foo').alias("fooColumn")).select('fooColumn.value', 'fooColumn.value2').show()  ----- ------  |value|value2|  ----- ------  | 10| null|  ----- ------   

Ответ №1:

Вы можете использовать transform функцию для обновления каждой структуры в foo массиве.

Вот пример:

 import pyspark.sql.functions as F  df.printSchema()  #root # |-- foo: array (nullable = true) # | |-- element: struct (containsNull = true) # | | |-- value: string (nullable = true) # | | |-- value2: long (nullable = true)  df1 = df.withColumn(  "foo",  F.expr("transform(foo, x -gt; struct(coalesce(x.value, 10) as value, x.value2 as value2))") )  

Теперь вы можете показать значение, df1 чтобы убедиться, что оно было обновлено:

 df1.select(F.expr("inline(foo)")).show() # ----- ------  #|value|value2| # ----- ------  #| 10| 30| # ----- ------   

Комментарии:

1. Спасибо вам за это @blackbishop. Это близко к тому, что мне нужно, но это означает, что он теряет все остальные столбцы в foo. Мне нужно сохранить их и просто отредактировать столбец значений.

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

3. Это здорово @blackbishop. Моя фактическая схема содержит около 20 столбцов в разделе foo, поэтому мне пришлось написать большое выражение, но оно хорошо работало. Спасибо