无法将字符串强制转换为Integer(Scala)

时间:2019-05-06 18:05:06

标签: scala apache-spark casting databricks

我正在使用Scala编写一个Spark项目,在该项目中,我需要根据“演示”数据集进行一些计算。我正在使用databricks平台。

我需要将我的数据框的第二列(trainingCoordDataFrame)传递到列表中。列表的类型必须为List [Int]。

数据帧如下所示:

> +---+---+---+---+
> |_c0|_c1|_c2|_c3|
> +---+---+---+---+
> |1  |0  |0  |a  |
> |11 |9  |1  |a  |
> |12 |2  |7  |c  |
> |13 |2  |9  |c  |
> |14 |2  |4  |b  |
> |15 |1  |3  |c  |
> |16 |4  |6  |c  |
> |17 |3  |5  |c  |
> |18 |5  |3  |a  |
> |2  |0  |1  |a  |
> |20 |8  |9  |c  |
> |3  |1  |0  |b  |
> |4  |3  |4  |b  |
> |5  |8  |7  |b  |
> |6  |4  |9  |b  |
> |7  |2  |5  |a  |
> |8  |1  |9  |a  |
> |9  |3  |6  |a  |
> +---+---+---+---+

我正在尝试使用以下命令创建我想要的列表:

val trainingCoordList = trainingCoordDataFrame.select("_c1").collect().map(each => (each.getAs[Int]("_c1"))).toList

来自编译器的消息是这样的:

  

java.lang.ClassCastException:无法将java.lang.String强制转换为   java.lang.Integer

请注意,过程是:

1)。将数据集从本地PC上传到数据块(因此无法使用标准数据)。

val mainDataFrame = spark.read.format("csv").option("header", "false").load("FileStore/tables/First_Spacial_Dataset_ByAris.csv")

2)创建数据框。 (第一步:随机拆分主数据框。第二步:删除不必要的列)

val Array(trainingDataFrame,testingDataFrame) = mainDataFrame.randomSplit(Array(0.8,0.2)) //step one
val trainingCoordDataFrame = trainingDataFrame.drop("_c0", "_c3") //step two

3)创建列表。 <-这是错误的命令。

达到我想要的结果的正确方法是什么?

2 个答案:

答案 0 :(得分:2)

我认为有几种方法可以解决此问题。

A)为CSV定义架构

例如:

  val customSchema = StructType(Array(
    StructField("_c0", IntegerType),
    StructField("_c1", IntegerType),
    StructField("_c2", IntegerType),
    StructField("_c3", StringType)))

当您阅读CSV时,将模式选项与我们之前创建的StructType一起添加

val mainDataFrame = spark.read.format("csv").option("header", "false").schema(customSchema).load("FileStore/tables/First_Spacial_Dataset_ByAris.csv")

现在,如果我们查看mainDataFrame.printSchema()命令的输出,我们将看到根据您的用例键入了列:

root
  |-- _c0: integer (nullable = true)
  |-- _c1: integer (nullable = true)
  |-- _c2: integer (nullable = true)
  |-- _c3: string (nullable = true)

这意味着我们实际上可以运行您的原始命令而不会出现错误。

trainingCoordDataFrame.select("_c2").map(r => r.getInt(0)).collect.toList

B)将整个列转换为Int

引用列本身而不是列名,然后将该列转换为IntegerType。现在列类型为Int,您可以在之前失败的地方再次使用getInt:

trainingCoordDataFrame.select($"_c2".cast(IntegerType)).map(r => r.getInt(0)).collect.toList

C)分别转换每个值

使用地图将每个单独的值强制转换为或检索为String,然后将其强制强制转换为Int

trainingCoordDataFrame.select("_c2").map(r => r.getString(0).toInt).collect.toList

答案 1 :(得分:1)

该列的值是string类型的,因此请将该列读为string并使用scala的string.toInt方法。 在这个地方施展演员肯定是错误的。

val trainingCoordList = trainingCoordDataFrame.select("_c1").collect().map(each => each.getAs[String]("_c1").toInt).toList

或将Dataset API与自定义架构一起使用,例如与元组