Scala Spark。通过DataType创建具有默认值的对象

时间:2019-06-17 13:19:39

标签: scala apache-spark types

我有一个org.apache.spark.sql.types.DataType对象的列表,例如,
val tps = [FloatType, LongType, FloatType, DoubleType], 我从数据框收到的是这样的:

val tps = dataFrame.schema
      .filter(f => f.dataType.isInstanceOf[NumericType])
      .map(f => f.dataType)

,对于此列表中的每种类型,我都需要创建一个具有默认值的相应类型的对象
[0.0, 0l, 0.0, 0.0]。 我该怎么办?

我尝试做

tps.map(t => t.getClass.newInstance())

,但是由于私有成员(can not access a member of class org.apache.spark.sql.types.LongType$ with modifiers "private")以及因为该语句试图创建DataType对象,而我却需要相应类型的对象,因此无法解决问题。

我刚接触Scala,有人可以帮忙吗?

2 个答案:

答案 0 :(得分:1)

我出于测试目的有这样的东西

handleCheckboxChange(e) {
  console.log('value of checkbox : ', e.target.checked);
}
render() {
  return <input type="checkbox" onChange={this.handleCheckboxChange.bind(this)} />
}

您可以添加类型,并将随机性替换为0。或者具有另一个方法调用.zero,该方法返回所有中性值。 隐式类的update方法是因为我通常出于测试目的而更新几个值。

您会致电object RowSampleMaker { var makerRunNumber = 1 def apply(schema: StructType): Row = new GenericRowWithSchema(schema.map(field => { makerRunNumber += 1 field.dataType match { case ShortType => makerRunNumber.toShort case IntegerType => makerRunNumber case LongType => makerRunNumber.toLong case FloatType => makerRunNumber.toFloat case DecimalType() => d(makerRunNumber) case DateType => new Date(System.currentTimeMillis) case TimestampType => new Timestamp(System.currentTimeMillis) case StringType => s"arbitrary-$makerRunNumber" case BooleanType => false case StructType(fields) => apply(StructType(fields)) case t => throw new Exception(s"Maker doesn't support generating $t") } }).toArray, schema) implicit class RowManipulation(row: Row) { def update(fieldName: String, value: Any): Row = new GenericRowWithSchema( row.toSeq.updated(row.fieldIndex(fieldName), value).toArray, row.schema ) } } 对于要生成的每一行,然后在该行之外创建一个数据框

答案 1 :(得分:1)

我遵循了@ fd8s0的提示,这就是我想出的:

  def mapToDefault(dataType: DataType): Number = {
    val defaultVal = 0.0
    dataType match {
      case ShortType => defaultVal.toShort
      case IntegerType => defaultVal.toInt
      case LongType => defaultVal.toLong
      case FloatType => defaultVal.toFloat
      case DoubleType => defaultVal.toDouble
      case t => null
    }
  }

...

val defaultValues = dataFrame.schema
    .filter(f => f.dataType.isInstanceOf[NumericType])
    .map(column => mapToDefault(column.dataType))

因此,mapToDefault方法将完成创建具有默认值的给定DataType实例的工作(在我的情况下,仅适用于数字类型)。