字符串不能转换为整数(Scala)

String cannot be cast to Integer(Scala)

我正在使用 Scala 编写一个 Spark 项目,我需要在其中根据 "demo" 数据集进行一些计算。我正在使用数据块平台。

我需要将我的数据框 (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 cannot be cast to java.lang.Integer

注意程序是:

1)将本地PC的数据集上传到databricks(所以不能使用标准数据)

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) 创建列表。 <- 这是错误的命令。

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

该列的值是字符串类型,因此将该列作为字符串读取并使用 Scala 的 string.toInt 方法。 这个地方演员绝对是错的。

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

或者将数据集 API 与自定义架构一起使用,例如有元组

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

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) 单独转换每个值

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

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