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
Transformacja
scala> rdd.map(r => r.toString.split(",")).map(r => (r(0), r(1).toInt)).collect()
Otrzymuję następujący błąd podczas przekształcania tego RDD przy użyciu mapy:
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)
Odpowiedzi:
0 dla odpowiedzi № 1Problem polega na tym, że próbujesz przekonwertować 1)
na liczbę, gdy dodatkowy nawias powoduje wyjątek NumberFormatException.
Spróbuj się zmienić r.toString.split(",").map(r => (r(0), r(1).toInt)).collect()
po prostu r.map(r => (r(0), r(1).toInt)).collect()
i zobacz, czy to naprawi.
0 dla odpowiedzi nr 2
To dlatego, że nie powinieneś używać toString :) Z twojego kodu:
rdd.map(r => r.toString.split(","))
Tutaj krotki (A, B)
są odwzorowane na ciąg (A, B)
, a następnie podzielisz go na (A
i B)
. Co jest dość zabawne, rdd szybko już pisze RDD[(String, Int)]
:)
Zamiast tego nie powinieneś używać toString i tej funkcji mapy. Możesz także:
rdd.map(r=> r.toString.replaceAll("(", "").replaceAll(")", "").split(","))
Więc zastąpisz () pustymi ciągami z wejściowego ciągu
0 dla odpowiedzi № 3
Twój ostatni krok sugeruje, że tworzysz RDD[Tuple2(String, Int)]
Ale twój pierwszy krok już został stworzony RDD[tuple2(String, Int)]
który jest tuple
i w scala uzyskanie elementów tuple
jest zrobione przez._1 , ._2
itp.
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
Więc myślę, że nie potrzebujesz .toInt
w drugim parametrze, ponieważ jest już an Int
. Tak więc wykonywanie poniższych czynności powinno działać
scala> rdd.map(r => (r._1, r._2)).collect
res0: Array[(String, Int)] = Array((A,1), (A,2), (B,1), (A,3), (B,2))
Jeśli nadal dołączasz .toInt
, nadal będzie działać
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))
Tak więc konwersja tuple2 na String i podzielenie łańcucha w celu przekształcenia go w pierwotną formę byłoby, jak sądzę, wyłącznie do celów testowych.
Jeśli to jest powód, to kiedy tuple2
jest konwertowane na String
przez .toString
(
i )
w zestawie są również wsporniki, które należy usunąć. Tak więc właściwym sposobem na zrobienie drugiego kroku byłoby
scala> rdd.map(r => r.toString().replaceAll("[()]", "").split(",")).map(r => (r(0), r(1).toInt)).collect
res2: Array[(String, Int)] = Array((A,1), (A,2), (B,1), (A,3), (B,2))