Как я могу преобразовать все десятичные столбцы в фрейме данных Scala в тип double? - PullRequest
0 голосов
/ 25 февраля 2020

У меня есть фрейм данных с десятичными и строковыми типами. Я хочу привести все десятичные столбцы к двойным, не называя их. Я попробовал это без успеха. Вид нового искры.

>df.printSchema

root

 |-- var1: decimal(38,10) (nullable = true)
 |-- var2: decimal(38,10) (nullable = true)
 |-- var3: decimal(38,10) (nullable = true)
…
150 more decimal and string columns

Я пытаюсь:

import org.apache.spark.sql.types._

val cols = df.columns.map(x => {
    if (x.dataType == DecimalType(38,0)) col(x).cast(DoubleType) 
    else col(x)
})

Я получаю

<console>:30: error: value dataType is not a member of String
           if (x.dataType == DecimalType(38,0)) col(x).cast(DoubleType)

1 Ответ

2 голосов
/ 25 февраля 2020

Проблема в том, что df.columns вернет список строк, содержащий имена столбцов. dataType, с другой стороны, является членом класса StructField . Чтобы получить DataType, вы должны использовать df.schema.fields. Это выведет список полей в Array[StructField]:

import org.apache.spark.sql.types.{StructField, DecimalType, DoubleType}
import org.apache.spark.sql.functions.col

val df = Seq(
(130, Decimal(122.45), "t1"),
(536, Decimal(1.45), "t2"),
(518, Decimal(0.45), "t3"))
.toDF("ID","decimal","tmp")

df.printSchema
// root
//  |-- ID: integer (nullable = false)
//  |-- decimal: decimal(38,18) (nullable = true)
//  |-- tmp: string (nullable = true)

val decimalSchema = df.schema.fields.map{f =>
  f match{
    case StructField(name:String, _:DecimalType, _, _) => col(name).cast(DoubleType)
    case _ => col(f.name)
  }
}

df.select(decimalSchema:_*).printSchema
// root
//  |-- ID: integer (nullable = false)
//  |-- decimal: double (nullable = true)
//  |-- tmp: string (nullable = true)

Карта вернет список столбцов, в которых DecimalType заменен DoubleType.

...