从元组列表中创建一个spark rdd并使用groupByKey

时间:2018-04-18 22:41:13

标签: python pyspark

我有一个像下面这样的元组列表

(?<=/> )(.* <p=".*"/>){3}(?= <head>)

我想使用pyspark和groupByKey来生成:

var username = [];
var usernameList = document.querySelectorAll('.msg.g_bot.bot.private.i ~ .msg .usr:nth-child(even)');
for (i of usernameList) {
    var name = i.childNodes[0].innerHTML;
    if (name !== undefined) {
        username.push(name);
    }
}
console.log(username);

我不知道如何制作一个spark rdd并使用groupByKey。

我试过了:

ls=[('c', 's'),('c', 'm'), ('c', 'p'), ('h', 'bi'), ('h', 'vi'), ('n', 'l'), ('n', 'nc')]
  

nc=[['c','s', 'm', 'p'], ['h','bi','vi'], ['n','l', 'nc']

2 个答案:

答案 0 :(得分:1)

您收到该错误是因为您的对象是list而不是rdd。 Python列表没有groupByKey()方法(如错误状态)。

您可以先使用rdd将您的列表转换为sc.parallelize

myrdd = sc.parallelize(ls)
nc = myrdd.groupByKey().collect()
print(nc)
#[('c',['s', 'm', 'p']), ('h',['bi','vi']), ('n',['l', 'nc'])]

这将返回一个元组列表,其中第一个元素是键,第二个元素是值列表。如果您想要展平这些元组,可以使用itertools.chain.from_iterable

from itertools import chain
nc = [tuple(chain.from_iterable(v)) for v in nc]
print(nc)
#[('c', 's', 'm', 'p'), ('h', 'bi', 'vi'), ('n', 'l', 'nc')]

但是,使用itertools.groupby

可以避免火花完全达到预期效果
from itertools import groupby, chain
ls=[('c', 's'),('c', 'm'), ('c', 'p'), ('h', 'bi'), ('h', 'vi'), ('n', 'l'), ('n', 'nc')]

nc = [
    (key,) + tuple(chain.from_iterable(g[1:] for g in list(group)))
    for key, group in groupby(ls, key=lambda x: x[0])
]
print(nc)
#[('c', 's', 'm', 'p'), ('h', 'bi', 'vi'), ('n', 'l', 'nc')]

答案 1 :(得分:0)

正如pault所提到的,这里的问题是Spark在专门的并行化数据集上运行,例如RDD。要获得使用groupByKey之后的确切格式,您需要使用列表做一些时髦的事情:

ls = sc.parallelize(ls)
tem=ls.groupByKey().map(lambda x: ([x[0]] + list(x[1]))).collect()
print(tem)
#[['h', 'bi', 'vi'], ['c', 's', 'm', 'p'], ['n', 'l', 'nc']]

但是,通常最好避免使用groupByKey,因为它可能会导致大量的shuffle。使用:

还可以使用reduceByKey解决此问题
ls=[('c', 's'),('c', 'm'), ('c', 'p'), ('h', 'bi'), ('h', 'vi'), ('n', 'l'), ('n', 'nc')]
ls = sc.parallelize(ls)
tem=ls.map(lambda x: (x[0], [x[1]])).reduceByKey(lambda x,y: x + y).collect()
print(tem)

这将更有效地扩展,但请注意,当您需要操作列表结构时,RDD操作可能会开始变得有点神秘。