Spark-文本文件到(String,String)

时间:2017-06-12 10:01:15

标签: apache-spark rdd

我有一个文本文件,其中有两个标签分隔的“列”

Japan<tab>Shinjuku
Australia<tab>Melbourne
United States of America<tab>New York
Australia<tab>Canberra
Australia<tab>Sydney
Japan<tab>Tokyo

我将此文件读入RDD并执行以下操作

val myFile = sc.textFile("/user/abc/textfile.txt")
myFile.map(str => str.split("\t")).collect()

导致

Array[Array[String]] = Array(Array(Japan,Tokyo), Array(United States of America,Washington DC), Array(Australia,Canberra))

但我想要的不是Array[Array[String]]而是Array[(String, String)],所以我尝试了以下

myFile.map(str => str.split("\t")).map(arr => (arr[0], arr[1])).collect

并收到以下错误

<console>:1: error: identifier expected but integer literal found.
   myFile.map(str => str.split("\t")).map(arr => (arr[0], arr[1])).collect
                                                     ^

有人可以帮我吗?我想要的是(国家,城市)列表,所以我可以执行以下操作

ListThatIWant(Country, City)
    .map(a => (a._1, 1))
        .reduceByKey(_+_)
            .reducebyKey((a, b) => if(a>b) a else b)

这将为我提供文本文件中城市数量最多的国家/地区,以及所述文件中的城市/出现次数。

2 个答案:

答案 0 :(得分:3)

在与scala不同的java中,使用()而非[]来访问数组元素 所以正确的方法是

myFile.map(str => str.split("\t")).map(arr => (arr(0), arr(1))).collect

答案 1 :(得分:1)

以下是用数据替换的简单示例;

val data = spark.sparkContext.parallelize(
  Seq(
    ("pan;Shinjuku"),
    ("Australia;Melbourne"),
      ("United States of America;New York"),
      ("Australia;Canberra"),
      ("Australia;Sydney"),
      ("Japan;Tokyo")
  ))

val exRDD = data.cache()
val result = exRDD.map(
    rec =>
      (rec.split(";")(0),rec.split(";")(1)))

result.foreach(println)

输出:

(pan,Shinjuku)
(Australia,Melbourne)
(United States of America,New York)
(Australia,Canberra)
(Australia,Sydney)
(Japan,Tokyo)

这也应该类似。 您试图使用错误的括号访问数组。

希望这有帮助