Я пишу программу Scala/spark, которая найдет максимальную зарплату сотрудника. Данные о сотрудниках доступны в файле CSV, а столбец зарплаты имеет разделитель запятой для тысяч, а также имеет префикс $ к нему, например. 74 628 долларов США.
Чтобы справиться с этой запятой и знаком доллара, я написал на scala функцию синтаксического анализатора, которая будет разбивать каждую строку на «,», а затем сопоставлять каждый столбец с отдельными переменными, которые будут присвоены классу case.
Моя программа парсера выглядит следующим образом. В этом, чтобы устранить запятую и знаки доллара, я использую функцию замены, чтобы заменить их пустыми, а затем, наконец, ввести Int.
def ParseEmployee(line: String): Classes.Employee = {
val fields = line.split(",")
val Name = fields(0)
val JOBTITLE = fields(2)
val DEPARTMENT = fields(3)
val temp = fields(4)
temp.replace(",","")//To eliminate the ,
temp.replace("$","")//To remove the $
val EMPLOYEEANNUALSALARY = temp.toInt //Type cast the string to Int
Classes.Employee(Name, JOBTITLE, DEPARTMENT, EMPLOYEEANNUALSALARY)
}
Мой класс Case выглядит следующим образом
case class Employee (Name: String,
JOBTITLE: String,
DEPARTMENT: String,
EMPLOYEEANNUALSALARY: Number,
)
Мой SQL-запрос Spark DataFrame выглядит следующим образом:
val empMaxSalaryValue = sc.sqlContext.sql("Select Max(EMPLOYEEANNUALSALARY) From EMP")
empMaxSalaryValue.show
когда я запускаю эту программу, я получаю следующее исключение
Exception in thread "main" java.lang.UnsupportedOperationException: No Encoder found for Number
- field (class: "java.lang.Number", name: "EMPLOYEEANNUALSALARY")
- root class: "Classes.Employee"
at org.apache.spark.sql.catalyst.ScalaReflection$.org$apache$spark$sql$catalyst$ScalaReflection$$serializerFor(ScalaReflection.scala:625)
at org.apache.spark.sql.catalyst.ScalaReflection$$anonfun$10.apply(ScalaReflection.scala:619)
at org.apache.spark.sql.catalyst.ScalaReflection$$anonfun$10.apply(ScalaReflection.scala:607)
at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:241)
at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:241)
at scala.collection.immutable.List.foreach(List.scala:381)
at scala.collection.TraversableLike$class.flatMap(TraversableLike.scala:241)
at scala.collection.immutable.List.flatMap(List.scala:344)
at org.apache.spark.sql.catalyst.ScalaReflection$.org$apache$spark$sql$catalyst$ScalaReflection$$serializerFor(ScalaReflection.scala:607)
at org.apache.spark.sql.catalyst.ScalaReflection$.serializerFor(ScalaReflection.scala:438)
at org.apache.spark.sql.catalyst.encoders.ExpressionEncoder$.apply(ExpressionEncoder.scala:71)
at org.apache.spark.sql.Encoders$.product(Encoders.scala:275)
at org.apache.spark.sql.SparkSession.createDataFrame(SparkSession.scala:282)
at org.apache.spark.sql.SQLContext.createDataFrame(SQLContext.scala:272)
at CalculateMaximumSalary$.main(CalculateMaximumSalary.scala:27)
at CalculateMaximumSalary.main(CalculateMaximumSalary.scala)
Любая идея, почему я получаю эту ошибку? в чем ошибка, которую я здесь делаю, и почему он не может привести тип к номеру?
Есть ли лучший подход к решению этой проблемы получения максимальной заработной платы работника?
BigDecimal
гораздо лучше подходит для денег, так как может с точностью обрабатывать как целые, так и десятичные числа 22.10.2017