java.lang.NumberFormatException:用于转换RDD时的输入字符串

时间:2017-08-12 19:29:11

标签: scala apache-spark

RDD

scala> val rdd = sc.parallelize(List(("A",1), ("A",2), ("B",1), ("A",3), ("B",2)))
rdd: org.apache.spark.rdd.RDD[(String, Int)] = ParallelCollectionRDD[806] at parallelize at <console>:30

转化

scala> rdd.map(r => r.toString.split(',')).map(r => (r(0), r(1).toInt)).collect()

使用map:

转换此RDD时出现以下错误
17/08/12 12:22:18 ERROR executor.Executor: Exception in task 2.0 in stage 161.0 (TID 7031)
java.lang.NumberFormatException: For input string: "1)"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)

3 个答案:

答案 0 :(得分:1)

问题是,当额外的括号导致NumberFormatException时,您试图将1)转换为数字。

尝试将r.toString.split(',').map(r => (r(0), r(1).toInt)).collect()更改为r.map(r => (r(0), r(1).toInt)).collect(),看看是否能解决问题。

答案 1 :(得分:1)

您的最后一步表明您正在创建RDD[Tuple2(String, Int)]

但是您的第一步已经创建了RDD[tuple2(String, Int)] tuple,而 scala 已经创建了tuple的元素。{{1}等等。

_1 , ._2

所以我猜你在第二个参数中不需要scala> val rdd = sc.parallelize(List(("A",1), ("A",2), ("B",1), ("A",3), ("B",2))) rdd: org.apache.spark.rdd.RDD[(String, Int)] = ParallelCollectionRDD[0] at parallelize at <console>:25 ,因为它已经是.toInt。所以做以下工作

Int

如果您仍然包含scala> rdd.map(r => (r._1, r._2)).collect res0: Array[(String, Int)] = Array((A,1), (A,2), (B,1), (A,3), (B,2)) ,它仍然可以使用

.toInt

因此,将tuple2转换为String并将字符串拆分为转换为原始形式,我认为仅用于测试目的。

如果这就是原因,当scala> rdd.map(r => (r._1, r._2.toInt)).collect res1: Array[(String, Int)] = Array((A,1), (A,2), (B,1), (A,3), (B,2)) tuple2 String转换为.toString时,还会包含(括号,需要删除。因此,采取第二步的正确方法是

)

答案 2 :(得分:0)

这是因为你不应该使用toString :)来自你的代码:

rdd.map(r => r.toString.split(','))

此处元组(A, B)映射到字符串(A, B),然后将其拆分为(AB)。什么很有趣,rdd fast已经输入RDD[(String, Int)]:)

相反,你不应该使用toString和这个map函数。你也可以这样做:

rdd.map(r=> r.toString.replaceAll("(", "").replaceAll(")", "").split(","))

因此,您将使用输入String

中的空字符串替换()