我有一个像下面这样的元组列表
(?<=/> )(.* <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']
答案 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操作可能会开始变得有点神秘。