2016-07-07 15 views
13

Sto provando a creare dinamicamente una riga in pySpark 1.6.1, quindi a crearla in un dataframe. L'idea generale è di estendere i risultati di describe per includere, ad esempio, skew e kurtosis. Ecco cosa ho pensato dovrebbe funzionare:Costruire una riga da un dict in 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) 

Ma questo torna TypeError: sequence item 0: expected string, dict found che è un errore abbastanza chiaro. Poi ho scoperto che se ho definito i campi riga prima, ho potuto utilizzare un 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}) 

che sarebbe un bel passo, tranne che non sembra come posso specificare in modo dinamico i campi in . Ho bisogno che funzioni per un numero sconosciuto di righe con nomi sconosciuti. Secondo la documentazione si può effettivamente andare nella direzione opposta:

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

Quindi sembra che dovrei essere in grado di farlo. Appare anche che potrebbero esserci alcune funzionalità deprecate dalle versioni precedenti che lo consentivano, ad esempio here. C'è un equivalente più attuale che mi manca?

risposta

17

È possibile utilizzare argomenti chiave disimballaggio come segue:

Row(**row_dict) 

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

E 'importante notare che internally sorts data by key per affrontare problems with older Python versions.

+0

È valido da una versione specifica di Python o è una regola generale? Il motivo per cui ti sto chiedendo è dovuto alla tua [ultima modifica] (https://stackoverflow.com/posts/38253641/revisions). – eliasah

+1

@eliasah Dato che Spark sarà sempre ordinato internamente, non importa quello che facciamo prima. E data la discussione su JIRA, non cambierà fino a quando Spark non rilasci il supporto per Python <3.6 (non molto presto). 'OrderedDict' era un po 'fuorviante, quindi l'ho rimosso. – zero323

+0

Ok grazie! Questa è stata l'origine della mia confusione. – eliasah

1

Nel caso in cui il dict non si appiattisca, è possibile convertire in modo ricorsivo dettare a riga.

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 
Problemi correlati