![](/img/trans.png)
[英]Spark - is map function available for Dataframe or just RDD?
[英]Spark: Using iterator lambda function in RDD map()
我在HDFS上有简单的数据集,正在将其加载到Spark中。 看起来像这样:
1 1 1 1 1 1 1
1 1 1 1 1 1 1
1 1 1 1 1 1 1
...
基本上是一个矩阵 我正在尝试实现一些需要对矩阵行进行分组的事情,因此,我试图为每一行添加一个唯一键,如下所示:
(1, [1 1 1 1 1 ... ])
(2, [1 1 1 1 1 ... ])
(3, [1 1 1 1 1 ... ])
...
我尝试了一些天真的尝试:设置全局变量并编写一个lambda函数以遍历全局变量:
# initialize global index
global global_index
global_index = 0
# function to generate keys
def generateKeys(x):
global_index+=1
return (global_index,x)
# read in data and operate on it
data = sc.textFile("/data.txt")
...some preprocessing...
data.map(generateKeys)
而且它似乎不认识全局变量的存在。
有没有想到的简单方法可以做到这一点?
谢谢杰克
>>> lsts = [
... [1, 1, 1, 1, 1, 1],
... [1, 1, 1, 1, 1, 1],
... [1, 1, 1, 1, 1, 1],
... [1, 1, 1, 1, 1, 1],
... [1, 1, 1, 1, 1, 1],
... [1, 1, 1, 1, 1, 1],
... [1, 1, 1, 1, 1, 2],
... [1, 1, 1, 2, 1, 2]
... ]
...
>>> list(enumerate(lsts))
[(0, [1, 1, 1, 1, 1, 1]),
(1, [1, 1, 1, 1, 1, 1]),
(2, [1, 1, 1, 1, 1, 1]),
(3, [1, 1, 1, 1, 1, 1]),
(4, [1, 1, 1, 1, 1, 1]),
(5, [1, 1, 1, 1, 1, 1]),
(6, [1, 1, 1, 1, 1, 2]),
(7, [1, 1, 1, 2, 1, 2])]
enumerate
为iterable中的每个项目生成唯一索引,并生成具有值的元组(index, original_item)
如果要从0
以外的数字开始编号,请将起始值传递为第二个参数进行enumerate
。
>>> list(enumerate(lsts, 1))
[(1, [1, 1, 1, 1, 1, 1]),
(2, [1, 1, 1, 1, 1, 1]),
(3, [1, 1, 1, 1, 1, 1]),
(4, [1, 1, 1, 1, 1, 1]),
(5, [1, 1, 1, 1, 1, 1]),
(6, [1, 1, 1, 1, 1, 1]),
(7, [1, 1, 1, 1, 1, 2]),
(8, [1, 1, 1, 2, 1, 2])]
请注意,该list
用于从enumerate
获取实数值,该enumerate
是迭代器而非函数,返回列表。
enumerate
易于使用,但是如果您需要在不同的代码段中添加id,它将变得困难或不可能。 对于这种情况,可以使用全球可用的生成器(如OP中的起草器)。
itertools
提供count
可以服务于我们的需要:
>>> from itertools import count
>>> idgen = count()
现在,我们已经有了(全球可用的) idgen
生成器,可以生成唯一的id。
我们可以通过函数prid
(打印ID)对其进行测试:
>>> def prid():
... id = idgen.next()
... print id
...
>>> prid()
0
>>> prid()
1
>>> prid()
2
>>> prid()
3
在工作时,我们可以在值列表上对其进行测试:
>>> lst = ['100', '101', '102', '103', '104', '105', '106', '107', '108', '109']
并定义实际函数,当使用值调用时将返回元组(id, value)
>>> def assignId(val):
... return (idgen.next(), val)
...
请注意,无需将idgen
声明为全局idgen
,因为我们不会更改其值( idgen
仅在被调用时会更改其内部状态,但仍将保持相同的生成器)。
测试是否可行:
>>> assignId("ahahah")
(4, 'ahahah')
并尝试在列表上:
>>> map(assignId, lst)
[(5, '100'),
(6, '101'),
(7, '102'),
(8, '103'),
(9, '104'),
(10, '105'),
(11, '106'),
(12, '107'),
(13, '108'),
(14, '109')]
enumerate
解决方案的主要区别在于,我们可以在代码中的任何位置逐一分配id,而无需在enumerate
所有处理中全部完成。
>>> assignId("lonely line")
(15, 'lonely line')
如果必须首先拥有索引,请尝试dataRdd.zipWithIndex
并最终交换结果元组。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.