为什么读取带空值的csv文件会导致IndexOutOfBoundException?

时间:2015-08-31 05:11:28

标签: csv apache-spark apache-spark-sql

我有一个带有foll结构的csv文件

Name | Val1 | Val2 | Val3 | Val4 | Val5
John     1      2
Joe      1      2
David    1      2            10    11

我可以将其加载到RDD中。我尝试创建一个架构,然后从Dataframe创建一个架构,并收到indexOutOfBound错误。

代码是这样的......

val rowRDD = fileRDD.map(p => Row(p(0), p(1), p(2), p(3), p(4), p(5), p(6) )

当我尝试对rowRDD执行操作时,会出错。

非常感谢任何帮助。

4 个答案:

答案 0 :(得分:2)

这不是你问题的答案。但它可能有助于解决您的问题。

从问题我看到您正在尝试从CSV创建数据框。

使用CSV创建数据框可以使用spark-csv

轻松完成

使用下面的spark-csv scala代码可以用来读取CSV val df = sqlContext.read.format("com.databricks.spark.csv").option("header", "true").load(csvFilePath)

对于您的样本数据,我得到了以下结果

+-----+----+----+----+----+----+
| Name|Val1|Val2|Val3|Val4|Val5|
+-----+----+----+----+----+----+
| John|   1|   2|    |    |    |
|  Joe|   1|   2|    |    |    |
|David|   1|   2|    |  10|  11|
+-----+----+----+----+----+----+

您还可以使用最新版本推断出解决方案。见answer

答案 1 :(得分:1)

如果CSV文件包含固定数量的列并且您的CVS看起来像这样,则空值不是问题(请注意用它分隔的空字段'自己的逗号):

David,1,2,10,,11

问题是您的CSV文件包含6列,但是:

val rowRDD = fileRDD.map(p => Row(p(0), p(1), p(2), p(3), p(4), p(5), p(6) )

您尝试阅读7列。只需将映射更改为:

val rowRDD = fileRDD.map(p => Row(p(0), p(1), p(2), p(3), p(4), p(5))

Spark将负责其余部分。

答案 2 :(得分:0)

该问题的可能解决方案是使用Double.NaN替换缺失值。假设我有一个带有列的文件example.csv

David,1,2,10,,11

您可以将csv文件作为文本文件阅读,如下所示

fileRDD=sc.textFile(example.csv).map(x=> {val y=x.split(","); val z=y.map(k=> if(k==""){Double.NaN}else{k.toDouble()})})

然后您可以使用您的代码从中创建数据框

答案 3 :(得分:0)

您可以执行以下操作。

val df = sqlContext
         .read
         .textfile(csvFilePath)
         .map(_.split(delimiter_of_file, -1)
         .map(
             p => 
              Row(
                p(0), 
                p(1),
                p(2),
                p(3),
                p(4),
                p(5),
                p(6))

使用文件分隔符分割。当您将-1设置为限制时,请考虑所有空白字段。