Подтвердить что ты не робот

Построение строки из 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

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

4b9b3361

Ответ 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