scala - Scala当我有两个键时如何使用reduceBykey
问题描述
一行数据格式:
id: 123456
Topiclist: ABCDE:1_8;5_10#BCDEF:1_3;7_11
一个 id 可以有很多行:
id: 123456
Topiclist:ABCDE:1_1;7_2;#BCDEF:1_2;7_11#
目标:(123456, (ABCDE,9,2),(BCDEF,5,2))
主题列表中的记录以 分隔#
,ABCDE:1_8;5_10
一条记录也是如此。
记录的格式为<topicid>:<topictype>_<topicvalue>
例如对于ABCDE:1_8
有
topicid = ABCDE
主题类型 = 1
主题值 = 8
目标:求和 的总和TopicType1
,so 的计数频率TopicType1
应为(id, (topicid, value,frequency))
,例如:(123456, (ABCDE,9,2),(BCDEF,5,2))
解决方案
假设您的数据是“123456!ABCDE:1_8;5_10#BCDEF:1_3;7_11”和“123456!ABCDE:1_1;7_2#BCDEF:1_2;7_11”,所以我们使用“!” 获取您的用户 ID“123456”
rdd.map{f=>
val userID = f.split("!")(0)
val items = f.split("!")(1).split("#")
var result = List[Array[String]]()
for (item <- items){
val topicID = item.split(":")(0)
for (topicTypeValue <- item.split(":")(1).split(";") ){
println(topicTypeValue);
if (topicTypeValue.split("_")(0)=="1"){result = result:+Array(topicID,topicTypeValue.split("_")(1),"1") }
}
}
(userID,result)
}
.flatMapValues(x=>x).filter(f=>f._2.length==3)
.map{f=>( (f._1,f._2(0)),(f._2(1).toInt,f._2(2).toInt) )}
.reduceByKey{case(x,y)=> (x._1+y._1,x._2+y._2) }
.map(f=>(f._1._1,(f._1._2,f._2._1,f._2._2))) // (userID, (TopicID,valueSum,frequences) )
输出为 ("12345",("ABCDE",9,2)), ("12345",("BCDEF",5,2)) 与您的输出略有不同,如果您确实需要,可以将此结果分组("12345",("ABCDE",9,2), ("BCDEF",5,2) )
推荐阅读
- gcloud - 尝试创建 gcloud cloud run 服务时,它显示“Cloud Run 在您的组织允许的区域不可用。”
- api - 跨不同项目重用微服务
- javascript - 如何在java脚本中消失输入字段(不是值)
- reactjs - 部署到 netlify 时,create-react-app 上的空白页
- amazon-web-services - 创建事物和证书时,AWS IOT 核心上的 MQTT 连接丢失
- python - 为什么此代码不返回我正在寻找的温度信息?
- javascript - 如何在页面加载时检查所选选项的值?
- python - Apache Web 服务器上的 Selenium 连接被拒绝
- node.js - 使用猫鼬节点 JS 获取 3 个模式值
- typescript - 使用时刻添加两个持续时间时出错