星火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
- 它可以被解析,不管引号如何。
使用inferSchema
属性,它可以自动识别列的数据类型。
var data= sparkSession.read
.option("header", hasColumnHeader)
.option("inferSchema", "true").csv(inputPath);
我不能使用inferSchema。它不适用于我所有的客户端数据集。我们有我们自己的推理模式函数,其指数性地更好地工作。我们检测到“123”和123都是数字,但我们如何告诉spark数据集忽略引号以避免NFE。 – DeeVu
为什么不能在将该列作为字符串读取后立即更改该列的数据类型? 你可以使用withColumnRenamed和withColumn api来解决这个问题。 – Varadha31590
我试过了。您不能将字符串列的数据类型更改为数字列,因为它会导致出现'java.lang.RuntimeException:java.lang.String不是bigint模式的有效外部类型' – DeeVu
不幸的是,那是我的错误。我没有在我的实际代码中使用字符。我从我的模式创建类中检索参数,它将字符串转换为字符而不是字符(为了简单起见,我不小心使用了'''''而不是'“\”“'。可能是Cloudera的Spark2版本和Java 2.1.1 maven版本的区别 – DeeVu
@DeeVu不,那不是 - 我只是修改了我的build.sbt以使用2.1.1,我的单元测试仍然是绿色的。你是如何定义你的模式的? –
好的。你说得对,这是一个模式问题。我的demoset试图将我的100列中的一列转换为小数时的整数。我可以放心地说我正在把我的头撞在我的桌子上。 – DeeVu