2016-07-07 40 views
13

我试图在pySpark 1.6.1中动态构建一行,然后将其构建到数据框中。总的想法是将describe的结果扩展到包括例如偏斜和峰度。这就是我认为应该工作:从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) 

但这返回TypeError: sequence item 0: expected string, dict found这是一个相当明显的错误。后来我发现,如果我第一次定义的行字段,我可以使用的字典:

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(name="Alice", age=11).asDict() == {'name': 'Alice', 'age': 11} 
True 

所以看起来我应该能够做到这一点。它也似乎可能有一些旧版本允许的不赞成使用的功能,例如here。有没有更多的当前相当于我失踪?

回答

17

您可以使用关键字参数拆包如下:

Row(**row_dict) 

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

需要注意的是它internally sorts data by key解决problems with older Python versions是很重要的。

+0

这是有效的从一个特定版本的Python还是一般规则?我问的原因是由于你的[最新编辑](https://stackoverflow.com/posts/38253641/revisions)。 – eliasah

+1

@eliasah由于Spark总是在内部进行排序,因此在此之前我们所做的并不重要。并且,在JIRA讨论之前,它不会改变,直到Spark支持Python <3.6(不会很快)。 'OrderedDict'有点误导,因此我删除了它。 – zero323

+0

好的,谢谢!那是我混乱的起源。 – eliasah

1

如果字典不平坦,可以递归地将字典转换为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