【问题标题】:Scala Spark. Create object with default value by DataType斯卡拉火花。通过 DataType 创建具有默认值的对象
【发布时间】:2019-10-31 02:24:34
【问题描述】:

我有一个 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 的新手,有人可以帮忙吗?

【问题讨论】:

    标签: scala apache-spark types


    【解决方案1】:

    我有类似这样的测试目的

    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
        )
      }
    }
    

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

    你会打电话给RowSampleMaker(schema).update("field1", value1).update("field2", value2) 对于您要生成的每一行,然后创建一个数据框

    【讨论】:

    • 谢谢!我按照您的提示为我的案例提出了解决方案。 (见下面我的回答)。
    【解决方案2】:

    我遵循了@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 实例的工作(在我的情况下仅适用于数字类型)。

    【讨论】:

      猜你喜欢
      • 2020-11-05
      • 2019-03-07
      • 2016-04-27
      • 2017-08-22
      • 1970-01-01
      • 2021-10-28
      • 2020-10-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多