Pyspark RDD“列表索引超出范围”错误

时间:2018-11-21 17:08:33

标签: python python-3.x pyspark rdd

我有以下形式的RDD:

[[['a'],['b,c,d','e,f,g']],[['h'],['i,j,k','l,m,n']]]

我想要实现的目标:

[['a ,b,c,d', 'a ,e,f,g'], ['h ,i,j,k', 'h ,l,m,n']]

我做了什么:

def pass_row(line):
  new_line = []
  key = ''.join(line[0])
  for el in line[1]:
    el = key +' ,'+ el
    new_line.append(el)
  return new_line

rdd.map(pass_row)

它适用于较小的数据样本。但是,当我尝试在整个数据集上运行它时,在list index out of range行上出现了for el in line[1]:

基本上,我有一个键(说['a']),用于['b,c,d','e,f,g']中的〜100套不同的值。我的最终目标是使它作为行形式的Spark数据框:

col1 col2 col3 col 4
a     b    c    d
a     e    f    g
h     i    j    k
h     l    m    n

谢谢您的任何建议!

1 个答案:

答案 0 :(得分:0)

您的错误似乎与您的数据有关,而不是与您的函数有关(这似乎是正确的,尽管有点复杂),而且您似乎将其应用于没有line[1]的行。

您是否可以确保line中元素的数量在实际数据集中是恒定的,例如使用:

def pass_row(line):
    assert len(line) == 2
    return [ "%s, %s" % (''.join(line[0]), el) for el in line[1]]

话虽如此,对于您的实际目标,您可能应该停止处理此后的字符串,而直接将数据作为2D数组获取,例如:

def pass_row(line):
    return [line[0] + el.split(',') for el in line[1]]

>>> a = [[['a'],['b,c,d','e,f,g']],[['h'],['i,j,k','l,m,n']]]
>>> b = [ pass_row(i) for i in a ]
>>> b
[[['a', 'b', 'c', 'd'], ['a', 'e', 'f', 'g']], [['h', 'i', 'j', 'k'], ['h', 'l', 'm', 'n']]]

在这里警告,您不能使用该解决方案直接提供DataFrame,因为每组前缀生成的行仍嵌套在其自己的列表中(这只是“二维数组的列表”)。

例如,使用sum函数,您可以轻松地在归约步骤中进行转置:

>>> sum(b, [])
[['a', 'b', 'c', 'd'], ['a', 'e', 'f', 'g'], ['h', 'i', 'j', 'k'], ['h', 'l', 'm', 'n']]

您的解决方案将因此需要3个步骤:

  • pass_row一样映射数据集
  • 使用内置于初始累加器sum的{​​{1}}内置函数来减少结果
  • 将结果提供给Spark DataFrame

在普通的Python中,以下代码可以完成工作

[]