使用Spark,我正在分析一个YouTube数据集,以查找上传最多视频数量的前五个类别。
加载数据:
val textRDD = sc.textFile("hdfs://quickstart.cloudera:8020/user/cloudera/spark/youtubedata.txt")
RDD的第一行
textRDD.first
res268: String = QuRYeRnAuXM EvilSquirrelPictures 1135 Pets & Animals 252 1075 4.96 46 86 gFa1YMEJFag nRcovJn9xHg 3TYqkBJ9YRk rSJ8QZWBegU 0TZqX5MbXMA UEvVksP91kg ZTopArY7Nbg 0RViGi2Rne8 HT_QlOJbDpg YZev1imoxX8 8qQrrfUTmh0 zQ83d_D2MGs u6_DQQjLsAw 73Wz9CQFDtE
通过提取第4列
创建RDDval countRDD = textRDD.map( line => line.split("\t")(3))
创建了一对
val pairRDD = countRDD.map(x => (x,1))
直到这里一切都运转良好。 最后一步是从列表中检索前5位
val result = pairRDD.reduceByKey(_ + _).sortByKey(false).take(5)
以上步骤返回以下错误:
17/06/07 07:55:59 ERROR executor.Executor: Exception in task 0.0 in stage 262.0 (TID 245) java.lang.ArrayIndexOutOfBoundsException: 3
at $line486.$read$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$anonfun$1.apply(<console>:32)
at $line486.$read$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$anonfun$1.apply(<console>:32)
at scala.collection.Iterator$$anon$11.next(Iterator.scala:328)
.
.
.
我哪里可能出错了?
答案 0 :(得分:0)
在您执行take
的最后一行中错误不,但在以下行中
val countRDD = textRDD.map( line => line.split("\t")(3))
使用textFile
api读取文件时,所有行都将转换为string
,因此不会保留\t
(制表符)。并且您无法使用"\t"
上面的语句只是一个transformation
所以没有抛出任何错误,但是当take
,action
被执行时,抛出了错误。
您必须通过在K的预期字符串的两侧插入拆分字符(字符串)来编辑输入文件,否则您必须找到分割读取行的适当方法。
答案 1 :(得分:0)
改变平原&#34; \ t&#34;拆分为line.split(&#34; \ s +&#34;);
\ s相当于[\ t \ n \ x0B \ f \ r \ n],应解决此问题。
答案 2 :(得分:0)
数据集中的某些行中存在空值。 所以,我修改了代码,它给出了正确的结果,没有任何错误。
val countRDD = textRDD.map(line => {val temp = line.split("\t"); if(temp.length >= 3)temp(3)})