Построение строки из dict в pySpark

Я пытаюсь динамически строить строку в pySpark 1.6.1, а затем встраивать ее в dataframe. Общая идея состоит в том, чтобы расширить результаты describe чтобы включить, например, перекос и эксцесс. Здесь то, что я думал, должно работать:

from pyspark.sql import Row

row_dict = {'C0': -1.1990072635132698,
            'C3': 0.12605772684660232,
            'C4': 0.5760856026559944,
            'C5': 0.1951877800894315,
            'C6': 24.72378589441825,
            'summary': 'kurtosis'}

new_row = Row(row_dict)

Но это возвращает TypeError: sequence item 0: expected string, dict found которая является довольно явной ошибкой. Затем я обнаружил, что если бы я сначала определял поля Row, я мог бы использовать dict:

r = Row('summary', 'C0', 'C3', 'C4', 'C5', 'C6')
r(row_dict)
> Row(summary={'summary': 'kurtosis', 'C3': 0.12605772684660232, 'C0': -1.1990072635132698, 'C6': 24.72378589441825, 'C5': 0.1951877800894315, 'C4': 0.5760856026559944})

Какой будет прекрасный шаг, за исключением того, что не кажется, что я могу динамически задавать поля в Row. Мне нужно, чтобы это работало для неизвестного количества строк с неизвестными именами. Согласно документации, вы можете пойти по-другому:

>>> Row(name="Alice", age=11).asDict() == {'name': 'Alice', 'age': 11}
True

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

Ответ 1

Вы можете использовать распаковку аргументов ключевых слов следующим образом:

Row(**row_dict)

## Row(C0=-1.1990072635132698, C3=0.12605772684660232, C4=0.5760856026559944, 
##     C5=0.1951877800894315, C6=24.72378589441825, summary='kurtosis')

Важно отметить, что он внутренне сортирует данные по ключевым словам для решения проблем со старыми версиями Python.

Ответ 2

Если dict не сглажен, вы можете преобразовать dict в Row рекурсивно.

def as_row(obj):
    if isinstance(obj, dict):
        dictionary = {k: as_row(v) for k, v in obj.items()}
        return Row(**dictionary)
    elif isinstance(obj, list):
        return [as_row(v) for v in obj]
    else:
        return obj