Строка не может быть приведена к Integer (Scala) - PullRequest
0 голосов
/ 06 мая 2019

Я пишу проект Spark с использованием Scala, в котором мне нужно сделать некоторые вычисления из «демонстрационных» наборов данных. Я использую платформу Databricks.

Мне нужно передать 2-й столбец моего Dataframe (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) Загрузка набора данных с локального ПК в блоки данных (поэтому стандартные данные использовать нельзя).

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) Создать список. <- вот ложная команда. </p>

Как правильно достичь желаемого результата?

Ответы [ 2 ]

2 голосов
/ 07 мая 2019

Я думаю, что есть несколько способов решить эту проблему.

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) Приведите каждое значение отдельно

Используйте карту для приведения или извлечения в качестве строки каждого отдельного значения, а затем приведите его к Int

trainingCoordDataFrame.select("_c2").map(r => r.getString(0).toInt).collect.toList
1 голос
/ 06 мая 2019

Значение столбца имеет тип string, поэтому читайте столбец как строку и используйте метод scala's string.toInt.В этом месте приведение определенно неверно.

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

Или используйте API набора данных с пользовательской схемой, например, с кортежами

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...