【问题标题】:Why does reading csv file with empty values lead to IndexOutOfBoundException?为什么读取空值的 csv 文件会导致 IndexOutOfBoundException?
【发布时间】:2015-11-25 01:55:32
【问题描述】:

我有一个带有 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 执行操作时,出现错误。

非常感谢任何帮助。

【问题讨论】:

  • 还显示错误,您可以了解更多。
  • 并粘贴示例 CSV,可能错误就在那里

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


【解决方案1】:

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

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

使用 spark-csv 包可以轻松地使用 CSV 创建数据框

使用scala代码下面的spark-csv可以用来读取一个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

【讨论】:

  • 谢谢!我会试试这个方法。似乎比我尝试的要好得多。
  • 无法让它工作。下载并构建了包,但我无法让它工作 spark-shell --packages com.databricks:spark-csv_2.11:1.2.0-s_2.11 jar 文件应该在哪里?它现在在 spark/bin 文件夹的路径中,但 spark-shell 找不到包。我做错了什么?
  • 我使用 [databricks] (databricks.com) 来做到这一点。但这也应该可以通过 spark-shell 实现。让我检查并更新你
  • 看来 spark-csv README 有问题。此命令有效bin/spark-shell --packages com.databricks:spark-csv_2.11:1.2.0。有了这个,我可以使用val df = sqlContext.read.format("com.databricks.spark.csv").option("header", "true").load("/home/sam/tmp/test.csv") 加载你的 CSV
  • 这行得通。感谢您对塞缪尔的所有帮助!非常感谢!
【解决方案2】:

如果 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 会处理剩下的事情。

【讨论】:

  • 您好,当我在这里键入问题时,p(6) 可能是一个错字。在我的真实程序中,列数确实匹配。还是有问题。谢谢!
【解决方案3】:

该问题的可能解决方案是用 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()})})

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

【讨论】:

    【解决方案4】:

    你可以这样做。

    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 设置为限制时,它会考虑所有空字段。

    【讨论】:

      猜你喜欢
      • 2017-03-04
      • 1970-01-01
      • 2021-06-27
      • 2013-04-07
      • 2018-10-11
      • 1970-01-01
      • 2011-05-10
      • 1970-01-01
      • 2012-03-25
      相关资源
      最近更新 更多