星火CSV阅读援引NUMERICS

问题描述:

我以CSV数据使用下面的代码当前正在阅读:星火CSV阅读援引NUMERICS

Dataset<Row> dataset = getSparkSession().read() 
      .option("header", "true") 
      .option("quote", '"') 
      .option("sep", ',') 
      .schema(schema) 
      .csv(path) 
      .toDF(); 

被引导到具有这个样子行的CSV文件:

"abc","city","123" 

为以及具有如下行的另一个文件:

"abc","city",123 

第二个工作正常,因为我传递的模式是

string, string, long 

的第一个结果java.lang.NumberFormatException: For input string: "123"

是否有可能为CSV读者正确读取两种有效格式的CSV?假设选项已通过。

我使用星火2.1.1

使用你的代码实际上是为我崩溃。我怀疑使用字符而不是字符串是罪魁祸首。使用'"'.toString代替.option("quote",...)可以修复崩溃问题并发挥作用。此外,您可能还想要定义转义字符,如下面的代码所示。

在Cloudera的Spark2,我能够使用以下方法来既引述和无引号号码解析到DecimalType,与预先定义的模式:解析的数字

spark.read 
      .option("mode", "FAILFAST") 
      .option("escape", "\"") 
      .option("delimiter", DELIMITER) 
      .option("header", HASHEADER.toString) 
      .option("quote", "\"") 
      .option("nullValue", null) 
      .option("ignoreLeadingWhiteSpace", value = true) 
      .schema(SCHEMA) 
      .csv(PATH) 

实例(从单元测试):

1.0 
11 
"15.23" 
"" 
//empty field 
"0.0000000001" 
1111111111111. 
000000000. //with leading space 

这也适用于我的测试IntegerType - 它可以被解析,不管引号如何。

+0

不幸的是,那是我的错误。我没有在我的实际代码中使用字符。我从我的模式创建类中检索参数,它将字符串转换为字符而不是字符(为了简单起见,我不小心使用了'''''而不是'“\”“'。可能是Cloudera的Spark2版本和Java 2.1.1 maven版本的区别 – DeeVu

+0

@DeeVu不,那不是 - 我只是修改了我的build.sbt以使用2.1.1,我的单元测试仍然是绿色的。你是如何定义你的模式的? –

+0

好的。你说得对,这是一个模式问题。我的demoset试图将我的100列中的一列转换为小数时的整数。我可以放心地说我正在把我的头撞在我的桌子上。 – DeeVu

使用inferSchema属性,它可以自动识别列的数据类型。

var data= sparkSession.read 
     .option("header", hasColumnHeader) 
     .option("inferSchema", "true").csv(inputPath); 
+0

我不能使用inferSchema。它不适用于我所有的客户端数据集。我们有我们自己的推理模式函数,其指数性地更好地工作。我们检测到“123”和123都是数字,但我们如何告诉spark数据集忽略引号以避免NFE。 – DeeVu

+0

为什么不能在将该列作为字符串读取后立即更改该列的数据类型? 你可以使用withColumnRenamed和withColumn api来解决这个问题。 – Varadha31590

+0

我试过了。您不能将字符串列的数据类型更改为数字列,因为它会导致出现'java.lang.RuntimeException:java.lang.String不是bigint模式的有效外部类型' – DeeVu