колонка, чтобы сделать это более понятным.

м, у меня есть следующие данные:

{"id":1, "payload":[{"foo":1, "lol":2},{"foo":2, "lol":2}]}

Я хотел бы взорвать полезную нагрузку и добавить столбец, например:

df = df.select('id', F.explode('payload').alias('data'))
df = df.withColumn('data.bar', F.col('data.foo') * 2)

Однако это приводит к кадру данных с тремя столбцами:

iddatadata.bar

Я ожидалdata.bar быть частьюdata структура ...

Как добавить столбец в разнесенную структуру вместо добавления столбца верхнего уровня?

 T. Gawęda13 сент. 2017 г., 21:42
 Justin Pihony13 сент. 2017 г., 21:25
Вам придется перестроить схему, используйтеselectили используйтеudf чтобы изменить данные - почти все эти варианты описаны здесь:stackoverflow.com/questions/31615657/...

Ответы на вопрос(1)

Решение Вопроса
df = df.withColumn('data', f.struct(
    df['data']['foo'].alias('foo'),
   (df['data']['foo'] * 2).alias('bar')
))

Это приведет к:

root
 |-- id: long (nullable = true)
 |-- data: struct (nullable = false)
 |    |-- col1: long (nullable = true)
 |    |-- bar: long (nullable = true)

ОБНОВИТЬ:

def func(x):
    tmp = x.asDict()
    tmp['foo'] = tmp.get('foo', 0) * 100
    res = zip(*tmp.items())
    return Row(*res[0])(*res[1])

df = df.withColumn('data', f.UserDefinedFunction(func, StructType(
    [StructField('foo', StringType()), StructField('lol', StringType())]))(df['data']))

Постскриптум

Искры почти не поддерживаютна месте opreation.

Поэтому каждый раз, когда вы хотите сделатьна местенужно сделатьзамещать фактически.

 surjikal14 сент. 2017 г., 22:45
Это определенно идет в правильном направлении! Есть ли способ сделать это, не зная о содержанииdata (Кромеdata.foo конечно)? Я отредактировал свой вопрос, чтобы добавить дополнительныйdata.lol колонка, чтобы сделать это более понятным.

Ваш ответ на вопрос