2016-07-07 7 views
13

Próbuję dynamicznie zbudować wiersz w pySpark 1.6.1, a następnie skompilować go w ramkę danych. Ogólną ideą jest rozszerzenie wyników describe na np. Pochylenie i kurtozę. Oto, co myślę powinny działać:Budowanie wiersza z dyktanda w pySpark

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) 

Ale to zwraca TypeError: sequence item 0: expected string, dict found który jest dość wyraźny błąd. Potem okazało się, że gdybym najpierw zdefiniowane pola rzędu, ja mógłby użyć 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}) 

co byłoby dobrym krokiem, oprócz tego, że nie wydaje się jak mogę dynamicznie określić pola w . Potrzebuję tego do pracy dla nieznanej liczby wierszy o nieznanych nazwach. Zgodnie z dokumentacją można przejść w inny sposób:

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

Wygląda na to, że powinienem móc to zrobić. Wygląda też na to, że niektóre starsze wersje mogą mieć pewne nieaktualne funkcje, na przykład here. Czy brakuje mi bardziej aktualnego odpowiednika?

Odpowiedz

17

Można użyć słów kluczowych argumentów rozpakowaniu następująco:

Row(**row_dict) 

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

Ważne jest, aby pamiętać, że internally sorts data by key zająć problems with older Python versions.

+0

Czy jest to poprawne z określonej wersji Pythona, czy jest to ogólna zasada? Przyczyna, o którą pytam, wynika z Twojej [najnowsza edycja] (https://stackoverflow.com/posts/38253641/revisions). – eliasah

+1

@eliasah Ponieważ Spark zawsze sortuje wewnętrznie, po prostu nie ma znaczenia, co robimy wcześniej. A biorąc pod uwagę dyskusję JIRA, nie zmieni się, dopóki Spark nie obniży wsparcia dla Pythona <3.6 (w najbliższym czasie). "OrderedDict" było trochę mylące, dlatego usunąłem go. – zero323

+0

Ok dzięki! To było źródło mojego zamieszania. – eliasah

1

Jeśli dyktatura nie jest spłaszczona, można przekonwertować dykturę do wiersza rekursywnie.

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