使用Spark从目录中读取多个文件

时间:2015-06-25 12:59:36

标签: scala hadoop apache-spark kaggle

我正在尝试使用spark:

在kaggle解决这个problem

输入的层次结构如下:

drivers/{driver_id}/trip#.csv
e.g., drivers/1/1.csv
      drivers/1/2.csv
      drivers/2/1.csv

我想阅读父目录“drivers”,对于每个子目录,我想创建一个 pairRDD ,密钥为(sub_directory,file_name) 和值作为文件的内容

我查看了this链接并尝试使用

val text = sc.wholeTextFiles("drivers")
text.collect()

这失败了,错误:

java.lang.ArrayIndexOutOfBoundsException: 0
    at org.apache.hadoop.mapreduce.lib.input.CombineFileInputFormat$OneFileInfo.<init>(CombineFileInputFormat.java:591)
    at org.apache.hadoop.mapreduce.lib.input.CombineFileInputFormat.getMoreSplits(CombineFileInputFormat.java:283)
    at org.apache.hadoop.mapreduce.lib.input.CombineFileInputFormat.getSplits(CombineFileInputFormat.java:243)
    at org.apache.spark.rdd.WholeTextFileRDD.getPartitions(NewHadoopRDD.scala:267)
    at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:219)
    at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:217)
    at scala.Option.getOrElse(Option.scala:120)
    at org.apache.spark.rdd.RDD.partitions(RDD.scala:217)
    at org.apache.spark.SparkContext.runJob(SparkContext.scala:1779)
    at org.apache.spark.rdd.RDD$$anonfun$collect$1.apply(RDD.scala:885)
    at org.apache.spark.rdd.RDDOperationScope$.withScope(RDDOperationScope.scala:148)
    at org.apache.spark.rdd.RDDOperationScope$.withScope(RDDOperationScope.scala:109)
    at org.apache.spark.rdd.RDD.withScope(RDD.scala:286)
    at org.apache.spark.rdd.RDD.collect(RDD.scala:884)

但是当我运行下面的代码时,它可以工作。

val text =  sc.wholeTextFiles("drivers/1")
text.collect()

但我不想这样做,因为在这里我必须阅读目录 drivers 并循环文件并为每个条目调用 wholeTextFiles

1 个答案:

答案 0 :(得分:1)

而不是使用

NoClassDefFoundError

您可以使用这段代码。因为spark内部列出了文件夹和子文件夹的所有可能值,因此它可能会花费您在大型数据集上的时间。而不是你可以使用联盟来达到同样的目的。

将包含位置的List对象传递给下面的代码段,注意:sc是SQLContext的对象

sc.textfile("path/*/**") or sc.wholeTextFiles("path/*")

现在你有一个最终的统一RDD,即df