У меня есть фрейм данных со столбцом, который содержит массив, содержащий структуры формы (ключ, оценка), т.е. столбец значений ниже. Кроме того, у меня есть еще один столбец с именем item, который содержит строку.
root
|-- value: array (nullable = true)
| |-- element: struct (containsNull = true)
| | |-- key: string (nullable = true)
| | |-- score: double (nullable = true)
|-- id: string (nullable = true)
|-- item: string (nullable = true)
Когда элемент не равен нулю, я хочу выполнить поиск в массиве, чтобы увидеть, присутствует ли элемент в value.key(s). Если его нет, добавьте (item, min) к массиву в столбце значений. Здесь min — это минимальное значение для оценок в массиве. Мне нужно сохранить порядок элементов в массиве и добавить новую структуру в конец списка.
Пример ввода:
+-----------------------------------+------+------+
| value | id | item |
+-----------------------------------+------+------+
|[[e1, 0.4] , [e2, 0.3]] | 1 | e3 |
|[[e1, 0.4] , [e2, 0.3], [e3, 0.2]] | 2 | e4 |
|[[e1, 0.4] , [e2, 0.3]] | 3 | e1 |
|[[e1, 0.4] , [e2, 0.3]] | 4 | null |
+-----------------------------------+------+------+
Пример вывода:
+------------------------------------------------+------+------+
| value | id | item |
+------------------------------------------------+------+------+
|[[e1, 0.4] , [e2, 0.3], [e3, 0.3]] | 1 | e3 |
|[[e1, 0.4] , [e2, 0.3], [e3, 0.2], [e4, 0.2]] | 2 | e4 |
|[[e1, 0.4] , [e2, 0.3]] | 3 | e1 |
|[[e1, 0.4] , [e2, 0.3]] | 4 | null |
+------------------------------------------------+------+------+
Как изменится решение, если я захочу добавить новый (ключ, счет) в определенную позицию в списке? (например, начало или середина)
Вы можете определить функцию udf
для ее достижения.
import pyspark.sql.functions as F
from pyspark.sql.types import StructType,StructField,ArrayType,StringType,DoubleType
def contains(values,item):
if not item:
return values
keys = [pair['key'] for pair in values]
if item not in keys:
scores = [pair['score'] for pair in values]
values.append({'key':item,'score':min(scores)})
return values
contains_udf = F.udf(contains,ArrayType(StructType([StructField('key', StringType()),
StructField('score', DoubleType())])))
df = df.withColumn("value", contains_udf('value','item'))
df.show(truncate = False)
+--------------------------------------------+---+----+
|value |id |item|
+--------------------------------------------+---+----+
|[[e1, 0.4], [e2, 0.3], [e3, 0.3]] |1 |e3 |
|[[e1, 0.4], [e2, 0.3], [e3, 0.2], [e4, 0.2]]|2 |e4 |
|[[e1, 0.4], [e2, 0.3]] |3 |e1 |
|[[e1, 0.4], [e2, 0.3]] |4 |null|
+--------------------------------------------+---+----+