我正在使用Scala和spark - 初学者程序员和海报 - 目标是将每个请求(行)映射到一对(userid,1)然后对命中数进行求和。
任何人都可以更详细地解释第1和第3行发生了什么, =>
:line => line.split
的含义是什么?
请原谅我的帖子格式中的任何错误,因为我是这个网站的新手。
val userreqs = logs.map(line => line.split(' ')).
map(words => (words(2),1)).
reduceByKey((v1,v2) => v1 + v2)
答案 0 :(得分:1)
考虑以下假设日志
trans_id amount user_id
1 100 A001
2 200 A002
3 300 A001
4 200 A003
这是如何在日志中执行的每个操作的spark中处理数据。
logs // RDD("1 100 A001","2 200 A002", "3 300 A001", "3 200 A003")
.map(line => line.split(' ')) // RDD(Array(1,100,A001),Array(2,200,A002),Array(3,300,A001), Array(4,200,A003))
.map(words => (words(2),1)) // RDD((A001,1), (A002,1), (A001,1), (A003,1))
.reduceByKey((v1,v2) => v1+v2) // RDD(A001,2),A(A002,1),A(`003,1))
line.split(' ')
将字符串拆分为String of Array。 “Hello World”=>数组(“你好”,“世界”)reduceByKey(_+_)
按键运行reduce操作分组数据。在这种情况下,它会添加key的所有值。在上面的示例中,用户密钥A001有两个出现,并且与每个密钥相关联的值为1.现在使用reduceByKey方法中提供的加法函数(_ + _
)将其减少为值2。 答案 1 :(得分:0)
line.split(' ')
用返回字符串数组
例如:
"hello spark scala".split(' ')
提供[hello, spark, scala]
`reduceByKey((v1,v2) => v1 + v2)` is equivalent to `reduceByKey(_ + _)`
以下是reduceByKey的工作原理https://i.stack.imgur.com/igmG3.gif和http://backtobazics.com/big-data/spark/apache-spark-reducebykey-example/
对于相同的密钥,它会不断添加所有值。
希望这有帮助!
答案 2 :(得分:0)
学习Spark和reduceByKey
的最简单方法是阅读PairRDDFunctions的官方文档:
reduceByKey(func:(V,V)⇒V):RDD [(K,V)] 使用关联和可交换的reduce函数合并每个键的值。
所以它基本上取每个键的所有值,并将它们加在一起得到一个值,该值是每个键的所有值的总和。
现在,你可能会问自己:
关键是什么?
理解密钥(双关语)的关键是看看如何生成密钥以及该行的角色
map(words => (words(2),1)).
您可以在此处words
将其解构为一对键和1
。
这是一种经典的map-reduce算法,您可以在下一步中为所有键提供1
以减少它们。
最后,在此map
之后,您将拥有一系列键值对,如下所示:
(hello, 1)
(world, 1)
(nice, 1)
(to, 1)
(see, 1)
(you, 1)
(again, 1)
(again, 1)
我故意重复最后一个(again, 1)
对,以向您显示对可以多次出现。
该系列是使用RDD.map
运算符创建的,该运算符采用分割单行并将其标记为单词的函数。
logs.map(line => line.split(' ')).
它的内容如下:
对于
line
中的每个logs
,使用line
(空格)作为分隔符将拆分为令牌。
我更改此行以使用像\\s+
这样的正则表达式,因此任何白色字符都会被视为分隔符的一部分。