繁体   English   中英

在Spark Dataframe中使用arraytype

[英]working with arraytype in spark Dataframe

我的要求是将DataFrame中的所有Decimal数据类型都转换为String。 逻辑在使用简单类型时可以正常工作,但在ArrayType上则不能工作。 这是逻辑:

var df = spark.sql("select * from test_1")
for(dt <- df.dtypes) {
  if(dt._2.substring(0,7) == "Decimal"){
    df = df.withColumn(dt._1,df(dt._1).cast("String"))  
  }
}

但是arrayType内的列尽管是十进制类型,但仍保持不变。 请帮助,如何遍历嵌套元素并将其转换为字符串。 这是我的数据框的架构:

scala> df.schema res77:org.apache.spark.sql.types.StructType = StructType(StructField(mstr_prov_id,StringType,true),StructField(prov_ctgry_cd,StringType,true),StructField(prov_orgnl_efctv_dt,TimestampType, prov_trmntn_dt,TimestampType,true),StructField(prov_trmntn_rsn_cd,StringType,true),StructField(npi_rqrd_ind,StringType,true),StructField(prov_stts_aray_txt,ArrayType(StructType(StructField(PROV_STTS_KEY)(CV_STTS_KEY) ,TimestampType,true),StructField(PROV_STTS_CD,StringType,true),StructField(PROV_STTS_TRMNTN_DT,TimestampType,true),StructField(PROV_STTS_TRMNTN_RSN_CD,StringType,true),true),true))

您还可以转换复杂的类型,例如,如果您有一个像这样的架构的数据框:

root
 |-- arr: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- i: decimal(22,0) (nullable = true)
 |    |    |-- j: double (nullable = false)

你可以投型小数的所有数组元素(场i通过执行此实例):

df
  .select($"arr".cast("array<struct<i:string,j:double>>"))
  .printSchema()

root
 |-- arr: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- i: string (nullable = true)
 |    |    |-- j: double (nullable = true)

编辑:如果您事先不知道该架构,则可以将原始架构中的decimal替换为string

val arraySchema = df.schema.fields(0).dataType.simpleString
val castedSchema = arraySchema.replaceAll("decimal\\(.*\\)","string")

df
  .select($"arr".cast(castedSchema))
  .show()

如果您使用的是Spark 2.1及更高版本,则后续投射应该适合您

val newSchema = DataType.fromJson(df.schema.json.replaceAll("(decimal\\(\\d+,\\d+\\))", "string")).asInstanceOf[StructType]
df.select(newSchema.map(field => col(field.name).cast(field.dataType)): _*)

应该将所有十进制类型转换为字符串类型。

但是,如果您使用的火花版本低于上述版本,并且由于struct列中有timestamp数据类型,您将遇到

TimestampType (of class org.apache.spark.sql.types.TimestampType$) scala.MatchError: TimestampType (of class org.apache.spark.sql.types.TimestampType$)

它的强制转换结构在Timestamp字段上失败,并且解析的强制结构 与timestamp字段失败

试试看(您与==的比较可能不是您想要的)

var df = spark.sql("select * from test_1")
for(dt <- df.dtypes) {
  if("Decimal".equalsIgnoreCase(dt._2.substring(0,Math.min(7, dt._2.length)))){
    df = df.withColumn(dt._1,df(dt._1).cast("String"))  
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM