Spark——一行代码转化Dataset/DataFrame部分列或所有列的数据类型


当需要把DataFrame中所有列的类型转换成另外一种类型,并且这个DataFrame中字段很多,一个一个地转换要写很多冗余代码,那么就可以使用如下这两种转换方式。

方式一:foldLeft() 函数

1. 转化所有列类型

通过foldLeft()函数从左到右依次处理集合中的每个元素,代码如下:

import org.apache.spark.sql.DataFrame
import org.apache.spark.sql.functions.col

val df: DataFrame = ...
val columns: Array[String] = df.columns

val df2: DataFrame = columns.foldLeft(df){(currentDF, column) => currentDF.withColumn(column, col(column).cast("string"))}
  • 变量columns:是一个String类型的数组,数组中的元素为df中的列名。
  • foldLeft函数:此函数以df为初始值,从左向右遍历columns数组,并把df的每一行和columns的每个元素作为参数传入foldLeft后面的函数中(也就是foldLeft后面的大括号中)。
  • withColumn():将每一列转换成String类型并赋值给当前列。如果存在同名的列,withColumn函数默认会进行覆盖。

2. 转化部分列类型

例如:将Date类型的列转成String类型。

val df: DataFrame = ...
val columns: Array[String] = df.columns

val df2: DataFrame = columns.foldLeft(df){(currentDF, column) => if ("date".equals(df.schema(column).dataType.typeName)) currentDF.withColumn(column, col(column).cast("string")) else currentDF}

方式二:map() 函数

1. 转化所有列类型

使用Scala中的map()函数处理集合中的每个元素,代码如下:

import org.apache.spark.sql.{Column, DataFrame}
import org.apache.spark.sql.functions.col

val df: DataFrame = ...
val columns: Array[String] = df.columns

val arrayColumn: Array[Column] = columns.map(column => col(column).cast("string"))
val df2: DataFrame = df.select(arrayColumn: _*)

通过map函数将columns中的每一列转换成String类型,并返回一个Column类型的数组,然后,将arrayColumn数组中的每个元素作为参数传入select函数中,就相当于df.select(col1, col2, col3, …)。

除此之外,这种写法还有一个很有用的场景:比如要在一个DataFrame中select出很多列(假如有几十个几百个),如果要一个个显示写出来,既不方便又会让代码显得很冗余,那么就可以使用这种写法:

  1. 先通过df.columns得到这个DataFrame中的所有列,返回一个包含所有列的数组;
  2. 再使用Scala中的这种语法进行查询df.select(arrayColumn :_*),非常简洁明了。

2. 转化部分列类型

例如:将Date类型的列转成String类型。

val df: DataFrame = ...
val columns: Array[String] = df.columns

val arrayColumn: Array[Column] = columns.map(column => if ("date".equals(df.schema(column).dataType.typeName)) col(column).cast("string") else col(column))
val df2: DataFrame = df.select(arrayColumn: _*)
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值